Statistics
| Branch: | Revision:

root / hw / usb / hcd-ehci.c @ 0cae7b1a

History | View | Annotate | Download (81.5 kB)

1 94527ead Gerd Hoffmann
/*
2 94527ead Gerd Hoffmann
 * QEMU USB EHCI Emulation
3 94527ead Gerd Hoffmann
 *
4 94527ead Gerd Hoffmann
 * Copyright(c) 2008  Emutex Ltd. (address@hidden)
5 522079dd Hans de Goede
 * Copyright(c) 2011-2012 Red Hat, Inc.
6 522079dd Hans de Goede
 *
7 522079dd Hans de Goede
 * Red Hat Authors:
8 522079dd Hans de Goede
 * Gerd Hoffmann <kraxel@redhat.com>
9 522079dd Hans de Goede
 * Hans de Goede <hdegoede@redhat.com>
10 94527ead Gerd Hoffmann
 *
11 94527ead Gerd Hoffmann
 * EHCI project was started by Mark Burkley, with contributions by
12 94527ead Gerd Hoffmann
 * Niels de Vos.  David S. Ahern continued working on it.  Kevin Wolf,
13 94527ead Gerd Hoffmann
 * Jan Kiszka and Vincent Palatin contributed bugfixes.
14 94527ead Gerd Hoffmann
 *
15 94527ead Gerd Hoffmann
 *
16 94527ead Gerd Hoffmann
 * This library is free software; you can redistribute it and/or
17 94527ead Gerd Hoffmann
 * modify it under the terms of the GNU Lesser General Public
18 94527ead Gerd Hoffmann
 * License as published by the Free Software Foundation; either
19 94527ead Gerd Hoffmann
 * version 2 of the License, or(at your option) any later version.
20 94527ead Gerd Hoffmann
 *
21 94527ead Gerd Hoffmann
 * This library is distributed in the hope that it will be useful,
22 94527ead Gerd Hoffmann
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 94527ead Gerd Hoffmann
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24 94527ead Gerd Hoffmann
 * Lesser General Public License for more details.
25 94527ead Gerd Hoffmann
 *
26 94527ead Gerd Hoffmann
 * You should have received a copy of the GNU General Public License
27 94527ead Gerd Hoffmann
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
28 94527ead Gerd Hoffmann
 */
29 94527ead Gerd Hoffmann
30 f1ae32a1 Gerd Hoffmann
#include "hw/hw.h"
31 94527ead Gerd Hoffmann
#include "qemu-timer.h"
32 f1ae32a1 Gerd Hoffmann
#include "hw/usb.h"
33 f1ae32a1 Gerd Hoffmann
#include "hw/pci.h"
34 94527ead Gerd Hoffmann
#include "monitor.h"
35 439a97cc Gerd Hoffmann
#include "trace.h"
36 0ce668bc Gerd Hoffmann
#include "dma.h"
37 ceab6f96 Hans de Goede
#include "sysemu.h"
38 94527ead Gerd Hoffmann
39 94527ead Gerd Hoffmann
#define EHCI_DEBUG   0
40 94527ead Gerd Hoffmann
41 26d53979 Gerd Hoffmann
#if EHCI_DEBUG
42 94527ead Gerd Hoffmann
#define DPRINTF printf
43 94527ead Gerd Hoffmann
#else
44 94527ead Gerd Hoffmann
#define DPRINTF(...)
45 94527ead Gerd Hoffmann
#endif
46 94527ead Gerd Hoffmann
47 94527ead Gerd Hoffmann
/* internal processing - reset HC to try and recover */
48 94527ead Gerd Hoffmann
#define USB_RET_PROCERR   (-99)
49 94527ead Gerd Hoffmann
50 94527ead Gerd Hoffmann
#define MMIO_SIZE        0x1000
51 94527ead Gerd Hoffmann
52 94527ead Gerd Hoffmann
/* Capability Registers Base Address - section 2.2 */
53 94527ead Gerd Hoffmann
#define CAPREGBASE       0x0000
54 94527ead Gerd Hoffmann
#define CAPLENGTH        CAPREGBASE + 0x0000  // 1-byte, 0x0001 reserved
55 94527ead Gerd Hoffmann
#define HCIVERSION       CAPREGBASE + 0x0002  // 2-bytes, i/f version #
56 94527ead Gerd Hoffmann
#define HCSPARAMS        CAPREGBASE + 0x0004  // 4-bytes, structural params
57 94527ead Gerd Hoffmann
#define HCCPARAMS        CAPREGBASE + 0x0008  // 4-bytes, capability params
58 94527ead Gerd Hoffmann
#define EECP             HCCPARAMS + 1
59 94527ead Gerd Hoffmann
#define HCSPPORTROUTE1   CAPREGBASE + 0x000c
60 94527ead Gerd Hoffmann
#define HCSPPORTROUTE2   CAPREGBASE + 0x0010
61 94527ead Gerd Hoffmann
62 94527ead Gerd Hoffmann
#define OPREGBASE        0x0020        // Operational Registers Base Address
63 94527ead Gerd Hoffmann
64 94527ead Gerd Hoffmann
#define USBCMD           OPREGBASE + 0x0000
65 94527ead Gerd Hoffmann
#define USBCMD_RUNSTOP   (1 << 0)      // run / Stop
66 94527ead Gerd Hoffmann
#define USBCMD_HCRESET   (1 << 1)      // HC Reset
67 94527ead Gerd Hoffmann
#define USBCMD_FLS       (3 << 2)      // Frame List Size
68 94527ead Gerd Hoffmann
#define USBCMD_FLS_SH    2             // Frame List Size Shift
69 94527ead Gerd Hoffmann
#define USBCMD_PSE       (1 << 4)      // Periodic Schedule Enable
70 94527ead Gerd Hoffmann
#define USBCMD_ASE       (1 << 5)      // Asynch Schedule Enable
71 94527ead Gerd Hoffmann
#define USBCMD_IAAD      (1 << 6)      // Int Asynch Advance Doorbell
72 94527ead Gerd Hoffmann
#define USBCMD_LHCR      (1 << 7)      // Light Host Controller Reset
73 94527ead Gerd Hoffmann
#define USBCMD_ASPMC     (3 << 8)      // Async Sched Park Mode Count
74 94527ead Gerd Hoffmann
#define USBCMD_ASPME     (1 << 11)     // Async Sched Park Mode Enable
75 94527ead Gerd Hoffmann
#define USBCMD_ITC       (0x7f << 16)  // Int Threshold Control
76 94527ead Gerd Hoffmann
#define USBCMD_ITC_SH    16            // Int Threshold Control Shift
77 94527ead Gerd Hoffmann
78 94527ead Gerd Hoffmann
#define USBSTS           OPREGBASE + 0x0004
79 94527ead Gerd Hoffmann
#define USBSTS_RO_MASK   0x0000003f
80 94527ead Gerd Hoffmann
#define USBSTS_INT       (1 << 0)      // USB Interrupt
81 94527ead Gerd Hoffmann
#define USBSTS_ERRINT    (1 << 1)      // Error Interrupt
82 94527ead Gerd Hoffmann
#define USBSTS_PCD       (1 << 2)      // Port Change Detect
83 94527ead Gerd Hoffmann
#define USBSTS_FLR       (1 << 3)      // Frame List Rollover
84 94527ead Gerd Hoffmann
#define USBSTS_HSE       (1 << 4)      // Host System Error
85 94527ead Gerd Hoffmann
#define USBSTS_IAA       (1 << 5)      // Interrupt on Async Advance
86 94527ead Gerd Hoffmann
#define USBSTS_HALT      (1 << 12)     // HC Halted
87 94527ead Gerd Hoffmann
#define USBSTS_REC       (1 << 13)     // Reclamation
88 94527ead Gerd Hoffmann
#define USBSTS_PSS       (1 << 14)     // Periodic Schedule Status
89 94527ead Gerd Hoffmann
#define USBSTS_ASS       (1 << 15)     // Asynchronous Schedule Status
90 94527ead Gerd Hoffmann
91 94527ead Gerd Hoffmann
/*
92 94527ead Gerd Hoffmann
 *  Interrupt enable bits correspond to the interrupt active bits in USBSTS
93 94527ead Gerd Hoffmann
 *  so no need to redefine here.
94 94527ead Gerd Hoffmann
 */
95 94527ead Gerd Hoffmann
#define USBINTR              OPREGBASE + 0x0008
96 94527ead Gerd Hoffmann
#define USBINTR_MASK         0x0000003f
97 94527ead Gerd Hoffmann
98 94527ead Gerd Hoffmann
#define FRINDEX              OPREGBASE + 0x000c
99 94527ead Gerd Hoffmann
#define CTRLDSSEGMENT        OPREGBASE + 0x0010
100 94527ead Gerd Hoffmann
#define PERIODICLISTBASE     OPREGBASE + 0x0014
101 94527ead Gerd Hoffmann
#define ASYNCLISTADDR        OPREGBASE + 0x0018
102 94527ead Gerd Hoffmann
#define ASYNCLISTADDR_MASK   0xffffffe0
103 94527ead Gerd Hoffmann
104 94527ead Gerd Hoffmann
#define CONFIGFLAG           OPREGBASE + 0x0040
105 94527ead Gerd Hoffmann
106 94527ead Gerd Hoffmann
#define PORTSC               (OPREGBASE + 0x0044)
107 94527ead Gerd Hoffmann
#define PORTSC_BEGIN         PORTSC
108 94527ead Gerd Hoffmann
#define PORTSC_END           (PORTSC + 4 * NB_PORTS)
109 94527ead Gerd Hoffmann
/*
110 c44fd61c Hans de Goede
 * Bits that are reserved or are read-only are masked out of values
111 94527ead Gerd Hoffmann
 * written to us by software
112 94527ead Gerd Hoffmann
 */
113 a0a3167a Hans de Goede
#define PORTSC_RO_MASK       0x007001c0
114 94527ead Gerd Hoffmann
#define PORTSC_RWC_MASK      0x0000002a
115 94527ead Gerd Hoffmann
#define PORTSC_WKOC_E        (1 << 22)    // Wake on Over Current Enable
116 94527ead Gerd Hoffmann
#define PORTSC_WKDS_E        (1 << 21)    // Wake on Disconnect Enable
117 94527ead Gerd Hoffmann
#define PORTSC_WKCN_E        (1 << 20)    // Wake on Connect Enable
118 94527ead Gerd Hoffmann
#define PORTSC_PTC           (15 << 16)   // Port Test Control
119 94527ead Gerd Hoffmann
#define PORTSC_PTC_SH        16           // Port Test Control shift
120 94527ead Gerd Hoffmann
#define PORTSC_PIC           (3 << 14)    // Port Indicator Control
121 94527ead Gerd Hoffmann
#define PORTSC_PIC_SH        14           // Port Indicator Control Shift
122 94527ead Gerd Hoffmann
#define PORTSC_POWNER        (1 << 13)    // Port Owner
123 94527ead Gerd Hoffmann
#define PORTSC_PPOWER        (1 << 12)    // Port Power
124 94527ead Gerd Hoffmann
#define PORTSC_LINESTAT      (3 << 10)    // Port Line Status
125 94527ead Gerd Hoffmann
#define PORTSC_LINESTAT_SH   10           // Port Line Status Shift
126 94527ead Gerd Hoffmann
#define PORTSC_PRESET        (1 << 8)     // Port Reset
127 94527ead Gerd Hoffmann
#define PORTSC_SUSPEND       (1 << 7)     // Port Suspend
128 94527ead Gerd Hoffmann
#define PORTSC_FPRES         (1 << 6)     // Force Port Resume
129 94527ead Gerd Hoffmann
#define PORTSC_OCC           (1 << 5)     // Over Current Change
130 94527ead Gerd Hoffmann
#define PORTSC_OCA           (1 << 4)     // Over Current Active
131 94527ead Gerd Hoffmann
#define PORTSC_PEDC          (1 << 3)     // Port Enable/Disable Change
132 94527ead Gerd Hoffmann
#define PORTSC_PED           (1 << 2)     // Port Enable/Disable
133 94527ead Gerd Hoffmann
#define PORTSC_CSC           (1 << 1)     // Connect Status Change
134 94527ead Gerd Hoffmann
#define PORTSC_CONNECT       (1 << 0)     // Current Connect Status
135 94527ead Gerd Hoffmann
136 94527ead Gerd Hoffmann
#define FRAME_TIMER_FREQ 1000
137 adddecb1 Gerd Hoffmann
#define FRAME_TIMER_NS   (1000000000 / FRAME_TIMER_FREQ)
138 94527ead Gerd Hoffmann
139 94527ead Gerd Hoffmann
#define NB_MAXINTRATE    8        // Max rate at which controller issues ints
140 5cc194ca Gerd Hoffmann
#define NB_PORTS         6        // Number of downstream ports
141 94527ead Gerd Hoffmann
#define BUFF_SIZE        5*4096   // Max bytes to transfer per transaction
142 94527ead Gerd Hoffmann
#define MAX_QH           100      // Max allowable queue heads in a chain
143 8f74ed1e Hans de Goede
#define MIN_FR_PER_TICK  3        // Min frames to process when catching up
144 94527ead Gerd Hoffmann
145 94527ead Gerd Hoffmann
/*  Internal periodic / asynchronous schedule state machine states
146 94527ead Gerd Hoffmann
 */
147 94527ead Gerd Hoffmann
typedef enum {
148 94527ead Gerd Hoffmann
    EST_INACTIVE = 1000,
149 94527ead Gerd Hoffmann
    EST_ACTIVE,
150 94527ead Gerd Hoffmann
    EST_EXECUTING,
151 94527ead Gerd Hoffmann
    EST_SLEEPING,
152 94527ead Gerd Hoffmann
    /*  The following states are internal to the state machine function
153 94527ead Gerd Hoffmann
    */
154 94527ead Gerd Hoffmann
    EST_WAITLISTHEAD,
155 94527ead Gerd Hoffmann
    EST_FETCHENTRY,
156 94527ead Gerd Hoffmann
    EST_FETCHQH,
157 94527ead Gerd Hoffmann
    EST_FETCHITD,
158 2fe80192 Gerd Hoffmann
    EST_FETCHSITD,
159 94527ead Gerd Hoffmann
    EST_ADVANCEQUEUE,
160 94527ead Gerd Hoffmann
    EST_FETCHQTD,
161 94527ead Gerd Hoffmann
    EST_EXECUTE,
162 94527ead Gerd Hoffmann
    EST_WRITEBACK,
163 94527ead Gerd Hoffmann
    EST_HORIZONTALQH
164 94527ead Gerd Hoffmann
} EHCI_STATES;
165 94527ead Gerd Hoffmann
166 94527ead Gerd Hoffmann
/* macros for accessing fields within next link pointer entry */
167 94527ead Gerd Hoffmann
#define NLPTR_GET(x)             ((x) & 0xffffffe0)
168 94527ead Gerd Hoffmann
#define NLPTR_TYPE_GET(x)        (((x) >> 1) & 3)
169 94527ead Gerd Hoffmann
#define NLPTR_TBIT(x)            ((x) & 1)  // 1=invalid, 0=valid
170 94527ead Gerd Hoffmann
171 94527ead Gerd Hoffmann
/* link pointer types */
172 94527ead Gerd Hoffmann
#define NLPTR_TYPE_ITD           0     // isoc xfer descriptor
173 94527ead Gerd Hoffmann
#define NLPTR_TYPE_QH            1     // queue head
174 94527ead Gerd Hoffmann
#define NLPTR_TYPE_STITD         2     // split xaction, isoc xfer descriptor
175 94527ead Gerd Hoffmann
#define NLPTR_TYPE_FSTN          3     // frame span traversal node
176 94527ead Gerd Hoffmann
177 94527ead Gerd Hoffmann
178 94527ead Gerd Hoffmann
/*  EHCI spec version 1.0 Section 3.3
179 94527ead Gerd Hoffmann
 */
180 94527ead Gerd Hoffmann
typedef struct EHCIitd {
181 94527ead Gerd Hoffmann
    uint32_t next;
182 94527ead Gerd Hoffmann
183 94527ead Gerd Hoffmann
    uint32_t transact[8];
184 94527ead Gerd Hoffmann
#define ITD_XACT_ACTIVE          (1 << 31)
185 94527ead Gerd Hoffmann
#define ITD_XACT_DBERROR         (1 << 30)
186 94527ead Gerd Hoffmann
#define ITD_XACT_BABBLE          (1 << 29)
187 94527ead Gerd Hoffmann
#define ITD_XACT_XACTERR         (1 << 28)
188 94527ead Gerd Hoffmann
#define ITD_XACT_LENGTH_MASK     0x0fff0000
189 94527ead Gerd Hoffmann
#define ITD_XACT_LENGTH_SH       16
190 94527ead Gerd Hoffmann
#define ITD_XACT_IOC             (1 << 15)
191 94527ead Gerd Hoffmann
#define ITD_XACT_PGSEL_MASK      0x00007000
192 94527ead Gerd Hoffmann
#define ITD_XACT_PGSEL_SH        12
193 94527ead Gerd Hoffmann
#define ITD_XACT_OFFSET_MASK     0x00000fff
194 94527ead Gerd Hoffmann
195 94527ead Gerd Hoffmann
    uint32_t bufptr[7];
196 94527ead Gerd Hoffmann
#define ITD_BUFPTR_MASK          0xfffff000
197 94527ead Gerd Hoffmann
#define ITD_BUFPTR_SH            12
198 94527ead Gerd Hoffmann
#define ITD_BUFPTR_EP_MASK       0x00000f00
199 94527ead Gerd Hoffmann
#define ITD_BUFPTR_EP_SH         8
200 94527ead Gerd Hoffmann
#define ITD_BUFPTR_DEVADDR_MASK  0x0000007f
201 94527ead Gerd Hoffmann
#define ITD_BUFPTR_DEVADDR_SH    0
202 94527ead Gerd Hoffmann
#define ITD_BUFPTR_DIRECTION     (1 << 11)
203 94527ead Gerd Hoffmann
#define ITD_BUFPTR_MAXPKT_MASK   0x000007ff
204 94527ead Gerd Hoffmann
#define ITD_BUFPTR_MAXPKT_SH     0
205 94527ead Gerd Hoffmann
#define ITD_BUFPTR_MULT_MASK     0x00000003
206 e654887f Gerd Hoffmann
#define ITD_BUFPTR_MULT_SH       0
207 94527ead Gerd Hoffmann
} EHCIitd;
208 94527ead Gerd Hoffmann
209 94527ead Gerd Hoffmann
/*  EHCI spec version 1.0 Section 3.4
210 94527ead Gerd Hoffmann
 */
211 94527ead Gerd Hoffmann
typedef struct EHCIsitd {
212 94527ead Gerd Hoffmann
    uint32_t next;                  // Standard next link pointer
213 94527ead Gerd Hoffmann
    uint32_t epchar;
214 94527ead Gerd Hoffmann
#define SITD_EPCHAR_IO              (1 << 31)
215 94527ead Gerd Hoffmann
#define SITD_EPCHAR_PORTNUM_MASK    0x7f000000
216 94527ead Gerd Hoffmann
#define SITD_EPCHAR_PORTNUM_SH      24
217 94527ead Gerd Hoffmann
#define SITD_EPCHAR_HUBADD_MASK     0x007f0000
218 94527ead Gerd Hoffmann
#define SITD_EPCHAR_HUBADDR_SH      16
219 94527ead Gerd Hoffmann
#define SITD_EPCHAR_EPNUM_MASK      0x00000f00
220 94527ead Gerd Hoffmann
#define SITD_EPCHAR_EPNUM_SH        8
221 94527ead Gerd Hoffmann
#define SITD_EPCHAR_DEVADDR_MASK    0x0000007f
222 94527ead Gerd Hoffmann
223 94527ead Gerd Hoffmann
    uint32_t uframe;
224 94527ead Gerd Hoffmann
#define SITD_UFRAME_CMASK_MASK      0x0000ff00
225 94527ead Gerd Hoffmann
#define SITD_UFRAME_CMASK_SH        8
226 94527ead Gerd Hoffmann
#define SITD_UFRAME_SMASK_MASK      0x000000ff
227 94527ead Gerd Hoffmann
228 94527ead Gerd Hoffmann
    uint32_t results;
229 94527ead Gerd Hoffmann
#define SITD_RESULTS_IOC              (1 << 31)
230 94527ead Gerd Hoffmann
#define SITD_RESULTS_PGSEL            (1 << 30)
231 94527ead Gerd Hoffmann
#define SITD_RESULTS_TBYTES_MASK      0x03ff0000
232 94527ead Gerd Hoffmann
#define SITD_RESULTS_TYBYTES_SH       16
233 94527ead Gerd Hoffmann
#define SITD_RESULTS_CPROGMASK_MASK   0x0000ff00
234 94527ead Gerd Hoffmann
#define SITD_RESULTS_CPROGMASK_SH     8
235 94527ead Gerd Hoffmann
#define SITD_RESULTS_ACTIVE           (1 << 7)
236 94527ead Gerd Hoffmann
#define SITD_RESULTS_ERR              (1 << 6)
237 94527ead Gerd Hoffmann
#define SITD_RESULTS_DBERR            (1 << 5)
238 94527ead Gerd Hoffmann
#define SITD_RESULTS_BABBLE           (1 << 4)
239 94527ead Gerd Hoffmann
#define SITD_RESULTS_XACTERR          (1 << 3)
240 94527ead Gerd Hoffmann
#define SITD_RESULTS_MISSEDUF         (1 << 2)
241 94527ead Gerd Hoffmann
#define SITD_RESULTS_SPLITXSTATE      (1 << 1)
242 94527ead Gerd Hoffmann
243 94527ead Gerd Hoffmann
    uint32_t bufptr[2];
244 94527ead Gerd Hoffmann
#define SITD_BUFPTR_MASK              0xfffff000
245 94527ead Gerd Hoffmann
#define SITD_BUFPTR_CURROFF_MASK      0x00000fff
246 94527ead Gerd Hoffmann
#define SITD_BUFPTR_TPOS_MASK         0x00000018
247 94527ead Gerd Hoffmann
#define SITD_BUFPTR_TPOS_SH           3
248 94527ead Gerd Hoffmann
#define SITD_BUFPTR_TCNT_MASK         0x00000007
249 94527ead Gerd Hoffmann
250 94527ead Gerd Hoffmann
    uint32_t backptr;                 // Standard next link pointer
251 94527ead Gerd Hoffmann
} EHCIsitd;
252 94527ead Gerd Hoffmann
253 94527ead Gerd Hoffmann
/*  EHCI spec version 1.0 Section 3.5
254 94527ead Gerd Hoffmann
 */
255 94527ead Gerd Hoffmann
typedef struct EHCIqtd {
256 94527ead Gerd Hoffmann
    uint32_t next;                    // Standard next link pointer
257 94527ead Gerd Hoffmann
    uint32_t altnext;                 // Standard next link pointer
258 94527ead Gerd Hoffmann
    uint32_t token;
259 94527ead Gerd Hoffmann
#define QTD_TOKEN_DTOGGLE             (1 << 31)
260 94527ead Gerd Hoffmann
#define QTD_TOKEN_TBYTES_MASK         0x7fff0000
261 94527ead Gerd Hoffmann
#define QTD_TOKEN_TBYTES_SH           16
262 94527ead Gerd Hoffmann
#define QTD_TOKEN_IOC                 (1 << 15)
263 94527ead Gerd Hoffmann
#define QTD_TOKEN_CPAGE_MASK          0x00007000
264 94527ead Gerd Hoffmann
#define QTD_TOKEN_CPAGE_SH            12
265 94527ead Gerd Hoffmann
#define QTD_TOKEN_CERR_MASK           0x00000c00
266 94527ead Gerd Hoffmann
#define QTD_TOKEN_CERR_SH             10
267 94527ead Gerd Hoffmann
#define QTD_TOKEN_PID_MASK            0x00000300
268 94527ead Gerd Hoffmann
#define QTD_TOKEN_PID_SH              8
269 94527ead Gerd Hoffmann
#define QTD_TOKEN_ACTIVE              (1 << 7)
270 94527ead Gerd Hoffmann
#define QTD_TOKEN_HALT                (1 << 6)
271 94527ead Gerd Hoffmann
#define QTD_TOKEN_DBERR               (1 << 5)
272 94527ead Gerd Hoffmann
#define QTD_TOKEN_BABBLE              (1 << 4)
273 94527ead Gerd Hoffmann
#define QTD_TOKEN_XACTERR             (1 << 3)
274 94527ead Gerd Hoffmann
#define QTD_TOKEN_MISSEDUF            (1 << 2)
275 94527ead Gerd Hoffmann
#define QTD_TOKEN_SPLITXSTATE         (1 << 1)
276 94527ead Gerd Hoffmann
#define QTD_TOKEN_PING                (1 << 0)
277 94527ead Gerd Hoffmann
278 94527ead Gerd Hoffmann
    uint32_t bufptr[5];               // Standard buffer pointer
279 94527ead Gerd Hoffmann
#define QTD_BUFPTR_MASK               0xfffff000
280 0ce668bc Gerd Hoffmann
#define QTD_BUFPTR_SH                 12
281 94527ead Gerd Hoffmann
} EHCIqtd;
282 94527ead Gerd Hoffmann
283 94527ead Gerd Hoffmann
/*  EHCI spec version 1.0 Section 3.6
284 94527ead Gerd Hoffmann
 */
285 94527ead Gerd Hoffmann
typedef struct EHCIqh {
286 94527ead Gerd Hoffmann
    uint32_t next;                    // Standard next link pointer
287 94527ead Gerd Hoffmann
288 94527ead Gerd Hoffmann
    /* endpoint characteristics */
289 94527ead Gerd Hoffmann
    uint32_t epchar;
290 94527ead Gerd Hoffmann
#define QH_EPCHAR_RL_MASK             0xf0000000
291 94527ead Gerd Hoffmann
#define QH_EPCHAR_RL_SH               28
292 94527ead Gerd Hoffmann
#define QH_EPCHAR_C                   (1 << 27)
293 94527ead Gerd Hoffmann
#define QH_EPCHAR_MPLEN_MASK          0x07FF0000
294 94527ead Gerd Hoffmann
#define QH_EPCHAR_MPLEN_SH            16
295 94527ead Gerd Hoffmann
#define QH_EPCHAR_H                   (1 << 15)
296 94527ead Gerd Hoffmann
#define QH_EPCHAR_DTC                 (1 << 14)
297 94527ead Gerd Hoffmann
#define QH_EPCHAR_EPS_MASK            0x00003000
298 94527ead Gerd Hoffmann
#define QH_EPCHAR_EPS_SH              12
299 94527ead Gerd Hoffmann
#define EHCI_QH_EPS_FULL              0
300 94527ead Gerd Hoffmann
#define EHCI_QH_EPS_LOW               1
301 94527ead Gerd Hoffmann
#define EHCI_QH_EPS_HIGH              2
302 94527ead Gerd Hoffmann
#define EHCI_QH_EPS_RESERVED          3
303 94527ead Gerd Hoffmann
304 94527ead Gerd Hoffmann
#define QH_EPCHAR_EP_MASK             0x00000f00
305 94527ead Gerd Hoffmann
#define QH_EPCHAR_EP_SH               8
306 94527ead Gerd Hoffmann
#define QH_EPCHAR_I                   (1 << 7)
307 94527ead Gerd Hoffmann
#define QH_EPCHAR_DEVADDR_MASK        0x0000007f
308 94527ead Gerd Hoffmann
#define QH_EPCHAR_DEVADDR_SH          0
309 94527ead Gerd Hoffmann
310 94527ead Gerd Hoffmann
    /* endpoint capabilities */
311 94527ead Gerd Hoffmann
    uint32_t epcap;
312 94527ead Gerd Hoffmann
#define QH_EPCAP_MULT_MASK            0xc0000000
313 94527ead Gerd Hoffmann
#define QH_EPCAP_MULT_SH              30
314 94527ead Gerd Hoffmann
#define QH_EPCAP_PORTNUM_MASK         0x3f800000
315 94527ead Gerd Hoffmann
#define QH_EPCAP_PORTNUM_SH           23
316 94527ead Gerd Hoffmann
#define QH_EPCAP_HUBADDR_MASK         0x007f0000
317 94527ead Gerd Hoffmann
#define QH_EPCAP_HUBADDR_SH           16
318 94527ead Gerd Hoffmann
#define QH_EPCAP_CMASK_MASK           0x0000ff00
319 94527ead Gerd Hoffmann
#define QH_EPCAP_CMASK_SH             8
320 94527ead Gerd Hoffmann
#define QH_EPCAP_SMASK_MASK           0x000000ff
321 94527ead Gerd Hoffmann
#define QH_EPCAP_SMASK_SH             0
322 94527ead Gerd Hoffmann
323 94527ead Gerd Hoffmann
    uint32_t current_qtd;             // Standard next link pointer
324 94527ead Gerd Hoffmann
    uint32_t next_qtd;                // Standard next link pointer
325 94527ead Gerd Hoffmann
    uint32_t altnext_qtd;
326 94527ead Gerd Hoffmann
#define QH_ALTNEXT_NAKCNT_MASK        0x0000001e
327 94527ead Gerd Hoffmann
#define QH_ALTNEXT_NAKCNT_SH          1
328 94527ead Gerd Hoffmann
329 94527ead Gerd Hoffmann
    uint32_t token;                   // Same as QTD token
330 94527ead Gerd Hoffmann
    uint32_t bufptr[5];               // Standard buffer pointer
331 94527ead Gerd Hoffmann
#define BUFPTR_CPROGMASK_MASK         0x000000ff
332 94527ead Gerd Hoffmann
#define BUFPTR_FRAMETAG_MASK          0x0000001f
333 94527ead Gerd Hoffmann
#define BUFPTR_SBYTES_MASK            0x00000fe0
334 94527ead Gerd Hoffmann
#define BUFPTR_SBYTES_SH              5
335 94527ead Gerd Hoffmann
} EHCIqh;
336 94527ead Gerd Hoffmann
337 94527ead Gerd Hoffmann
/*  EHCI spec version 1.0 Section 3.7
338 94527ead Gerd Hoffmann
 */
339 94527ead Gerd Hoffmann
typedef struct EHCIfstn {
340 94527ead Gerd Hoffmann
    uint32_t next;                    // Standard next link pointer
341 94527ead Gerd Hoffmann
    uint32_t backptr;                 // Standard next link pointer
342 94527ead Gerd Hoffmann
} EHCIfstn;
343 94527ead Gerd Hoffmann
344 eb36a88e Gerd Hoffmann
typedef struct EHCIPacket EHCIPacket;
345 0122f472 Gerd Hoffmann
typedef struct EHCIQueue EHCIQueue;
346 0122f472 Gerd Hoffmann
typedef struct EHCIState EHCIState;
347 0122f472 Gerd Hoffmann
348 0122f472 Gerd Hoffmann
enum async_state {
349 0122f472 Gerd Hoffmann
    EHCI_ASYNC_NONE = 0,
350 ef5b2344 Hans de Goede
    EHCI_ASYNC_INITIALIZED,
351 0122f472 Gerd Hoffmann
    EHCI_ASYNC_INFLIGHT,
352 0122f472 Gerd Hoffmann
    EHCI_ASYNC_FINISHED,
353 0122f472 Gerd Hoffmann
};
354 0122f472 Gerd Hoffmann
355 eb36a88e Gerd Hoffmann
struct EHCIPacket {
356 eb36a88e Gerd Hoffmann
    EHCIQueue *queue;
357 eb36a88e Gerd Hoffmann
    QTAILQ_ENTRY(EHCIPacket) next;
358 eb36a88e Gerd Hoffmann
359 eb36a88e Gerd Hoffmann
    EHCIqtd qtd;           /* copy of current QTD (being worked on) */
360 eb36a88e Gerd Hoffmann
    uint32_t qtdaddr;      /* address QTD read from                 */
361 eb36a88e Gerd Hoffmann
362 eb36a88e Gerd Hoffmann
    USBPacket packet;
363 eb36a88e Gerd Hoffmann
    QEMUSGList sgl;
364 eb36a88e Gerd Hoffmann
    int pid;
365 eb36a88e Gerd Hoffmann
    enum async_state async;
366 eb36a88e Gerd Hoffmann
    int usb_status;
367 eb36a88e Gerd Hoffmann
};
368 eb36a88e Gerd Hoffmann
369 0122f472 Gerd Hoffmann
struct EHCIQueue {
370 0122f472 Gerd Hoffmann
    EHCIState *ehci;
371 8ac6d699 Gerd Hoffmann
    QTAILQ_ENTRY(EHCIQueue) next;
372 adddecb1 Gerd Hoffmann
    uint32_t seen;
373 adddecb1 Gerd Hoffmann
    uint64_t ts;
374 ae0138a8 Gerd Hoffmann
    int async;
375 cae5d3f4 Hans de Goede
    int transact_ctr;
376 0122f472 Gerd Hoffmann
377 0122f472 Gerd Hoffmann
    /* cached data from guest - needs to be flushed
378 0122f472 Gerd Hoffmann
     * when guest removes an entry (doorbell, handshake sequence)
379 0122f472 Gerd Hoffmann
     */
380 eb36a88e Gerd Hoffmann
    EHCIqh qh;             /* copy of current QH (being worked on) */
381 eb36a88e Gerd Hoffmann
    uint32_t qhaddr;       /* address QH read from                 */
382 eb36a88e Gerd Hoffmann
    uint32_t qtdaddr;      /* address QTD read from                */
383 e59928b3 Gerd Hoffmann
    USBDevice *dev;
384 b4ea8664 Hans de Goede
    QTAILQ_HEAD(pkts_head, EHCIPacket) packets;
385 0122f472 Gerd Hoffmann
};
386 0122f472 Gerd Hoffmann
387 df5d5c5c Hans de Goede
typedef QTAILQ_HEAD(EHCIQueueHead, EHCIQueue) EHCIQueueHead;
388 df5d5c5c Hans de Goede
389 0122f472 Gerd Hoffmann
struct EHCIState {
390 94527ead Gerd Hoffmann
    PCIDevice dev;
391 0122f472 Gerd Hoffmann
    USBBus bus;
392 94527ead Gerd Hoffmann
    qemu_irq irq;
393 e57964f5 Avi Kivity
    MemoryRegion mem;
394 3e4f910c Gerd Hoffmann
    MemoryRegion mem_caps;
395 3e4f910c Gerd Hoffmann
    MemoryRegion mem_opreg;
396 3e4f910c Gerd Hoffmann
    MemoryRegion mem_ports;
397 a0a3167a Hans de Goede
    int companion_count;
398 16a2dee6 Gerd Hoffmann
399 16a2dee6 Gerd Hoffmann
    /* properties */
400 16a2dee6 Gerd Hoffmann
    uint32_t maxframes;
401 16a2dee6 Gerd Hoffmann
402 94527ead Gerd Hoffmann
    /*
403 94527ead Gerd Hoffmann
     *  EHCI spec version 1.0 Section 2.3
404 94527ead Gerd Hoffmann
     *  Host Controller Operational Registers
405 94527ead Gerd Hoffmann
     */
406 3e4f910c Gerd Hoffmann
    uint8_t caps[OPREGBASE];
407 94527ead Gerd Hoffmann
    union {
408 3e4f910c Gerd Hoffmann
        uint32_t opreg[(PORTSC_BEGIN-OPREGBASE)/sizeof(uint32_t)];
409 94527ead Gerd Hoffmann
        struct {
410 94527ead Gerd Hoffmann
            uint32_t usbcmd;
411 94527ead Gerd Hoffmann
            uint32_t usbsts;
412 94527ead Gerd Hoffmann
            uint32_t usbintr;
413 94527ead Gerd Hoffmann
            uint32_t frindex;
414 94527ead Gerd Hoffmann
            uint32_t ctrldssegment;
415 94527ead Gerd Hoffmann
            uint32_t periodiclistbase;
416 94527ead Gerd Hoffmann
            uint32_t asynclistaddr;
417 94527ead Gerd Hoffmann
            uint32_t notused[9];
418 94527ead Gerd Hoffmann
            uint32_t configflag;
419 94527ead Gerd Hoffmann
        };
420 94527ead Gerd Hoffmann
    };
421 3e4f910c Gerd Hoffmann
    uint32_t portsc[NB_PORTS];
422 0122f472 Gerd Hoffmann
423 94527ead Gerd Hoffmann
    /*
424 94527ead Gerd Hoffmann
     *  Internal states, shadow registers, etc
425 94527ead Gerd Hoffmann
     */
426 94527ead Gerd Hoffmann
    QEMUTimer *frame_timer;
427 0fb3e299 Gerd Hoffmann
    QEMUBH *async_bh;
428 9a773408 Gerd Hoffmann
    uint32_t astate;         /* Current state in asynchronous schedule */
429 9a773408 Gerd Hoffmann
    uint32_t pstate;         /* Current state in periodic schedule     */
430 94527ead Gerd Hoffmann
    USBPort ports[NB_PORTS];
431 a0a3167a Hans de Goede
    USBPort *companion_ports[NB_PORTS];
432 94527ead Gerd Hoffmann
    uint32_t usbsts_pending;
433 7efc17af Gerd Hoffmann
    uint32_t usbsts_frindex;
434 df5d5c5c Hans de Goede
    EHCIQueueHead aqueues;
435 df5d5c5c Hans de Goede
    EHCIQueueHead pqueues;
436 94527ead Gerd Hoffmann
437 9a773408 Gerd Hoffmann
    /* which address to look at next */
438 9a773408 Gerd Hoffmann
    uint32_t a_fetch_addr;
439 9a773408 Gerd Hoffmann
    uint32_t p_fetch_addr;
440 94527ead Gerd Hoffmann
441 0122f472 Gerd Hoffmann
    USBPacket ipacket;
442 0ce668bc Gerd Hoffmann
    QEMUSGList isgl;
443 0122f472 Gerd Hoffmann
444 adddecb1 Gerd Hoffmann
    uint64_t last_run_ns;
445 3a215326 Gerd Hoffmann
    uint32_t async_stepdown;
446 44272b0f Hans de Goede
    bool int_req_by_async;
447 0122f472 Gerd Hoffmann
};
448 94527ead Gerd Hoffmann
449 94527ead Gerd Hoffmann
#define SET_LAST_RUN_CLOCK(s) \
450 adddecb1 Gerd Hoffmann
    (s)->last_run_ns = qemu_get_clock_ns(vm_clock);
451 94527ead Gerd Hoffmann
452 94527ead Gerd Hoffmann
/* nifty macros from Arnon's EHCI version  */
453 94527ead Gerd Hoffmann
#define get_field(data, field) \
454 94527ead Gerd Hoffmann
    (((data) & field##_MASK) >> field##_SH)
455 94527ead Gerd Hoffmann
456 94527ead Gerd Hoffmann
#define set_field(data, newval, field) do { \
457 94527ead Gerd Hoffmann
    uint32_t val = *data; \
458 94527ead Gerd Hoffmann
    val &= ~ field##_MASK; \
459 94527ead Gerd Hoffmann
    val |= ((newval) << field##_SH) & field##_MASK; \
460 94527ead Gerd Hoffmann
    *data = val; \
461 94527ead Gerd Hoffmann
    } while(0)
462 94527ead Gerd Hoffmann
463 26d53979 Gerd Hoffmann
static const char *ehci_state_names[] = {
464 aac882e7 Gerd Hoffmann
    [EST_INACTIVE]     = "INACTIVE",
465 aac882e7 Gerd Hoffmann
    [EST_ACTIVE]       = "ACTIVE",
466 aac882e7 Gerd Hoffmann
    [EST_EXECUTING]    = "EXECUTING",
467 aac882e7 Gerd Hoffmann
    [EST_SLEEPING]     = "SLEEPING",
468 aac882e7 Gerd Hoffmann
    [EST_WAITLISTHEAD] = "WAITLISTHEAD",
469 aac882e7 Gerd Hoffmann
    [EST_FETCHENTRY]   = "FETCH ENTRY",
470 aac882e7 Gerd Hoffmann
    [EST_FETCHQH]      = "FETCH QH",
471 aac882e7 Gerd Hoffmann
    [EST_FETCHITD]     = "FETCH ITD",
472 aac882e7 Gerd Hoffmann
    [EST_ADVANCEQUEUE] = "ADVANCEQUEUE",
473 aac882e7 Gerd Hoffmann
    [EST_FETCHQTD]     = "FETCH QTD",
474 aac882e7 Gerd Hoffmann
    [EST_EXECUTE]      = "EXECUTE",
475 aac882e7 Gerd Hoffmann
    [EST_WRITEBACK]    = "WRITEBACK",
476 aac882e7 Gerd Hoffmann
    [EST_HORIZONTALQH] = "HORIZONTALQH",
477 26d53979 Gerd Hoffmann
};
478 26d53979 Gerd Hoffmann
479 26d53979 Gerd Hoffmann
static const char *ehci_mmio_names[] = {
480 aac882e7 Gerd Hoffmann
    [USBCMD]            = "USBCMD",
481 aac882e7 Gerd Hoffmann
    [USBSTS]            = "USBSTS",
482 aac882e7 Gerd Hoffmann
    [USBINTR]           = "USBINTR",
483 aac882e7 Gerd Hoffmann
    [FRINDEX]           = "FRINDEX",
484 aac882e7 Gerd Hoffmann
    [PERIODICLISTBASE]  = "P-LIST BASE",
485 aac882e7 Gerd Hoffmann
    [ASYNCLISTADDR]     = "A-LIST ADDR",
486 aac882e7 Gerd Hoffmann
    [CONFIGFLAG]        = "CONFIGFLAG",
487 26d53979 Gerd Hoffmann
};
488 94527ead Gerd Hoffmann
489 4b63a0df Hans de Goede
static int ehci_state_executing(EHCIQueue *q);
490 4b63a0df Hans de Goede
static int ehci_state_writeback(EHCIQueue *q);
491 b4ea8664 Hans de Goede
static int ehci_fill_queue(EHCIPacket *p);
492 4b63a0df Hans de Goede
493 26d53979 Gerd Hoffmann
static const char *nr2str(const char **n, size_t len, uint32_t nr)
494 94527ead Gerd Hoffmann
{
495 26d53979 Gerd Hoffmann
    if (nr < len && n[nr] != NULL) {
496 26d53979 Gerd Hoffmann
        return n[nr];
497 94527ead Gerd Hoffmann
    } else {
498 26d53979 Gerd Hoffmann
        return "unknown";
499 94527ead Gerd Hoffmann
    }
500 94527ead Gerd Hoffmann
}
501 94527ead Gerd Hoffmann
502 26d53979 Gerd Hoffmann
static const char *state2str(uint32_t state)
503 26d53979 Gerd Hoffmann
{
504 26d53979 Gerd Hoffmann
    return nr2str(ehci_state_names, ARRAY_SIZE(ehci_state_names), state);
505 26d53979 Gerd Hoffmann
}
506 26d53979 Gerd Hoffmann
507 a8170e5e Avi Kivity
static const char *addr2str(hwaddr addr)
508 26d53979 Gerd Hoffmann
{
509 3e4f910c Gerd Hoffmann
    return nr2str(ehci_mmio_names, ARRAY_SIZE(ehci_mmio_names),
510 3e4f910c Gerd Hoffmann
                  addr + OPREGBASE);
511 26d53979 Gerd Hoffmann
}
512 26d53979 Gerd Hoffmann
513 439a97cc Gerd Hoffmann
static void ehci_trace_usbsts(uint32_t mask, int state)
514 439a97cc Gerd Hoffmann
{
515 439a97cc Gerd Hoffmann
    /* interrupts */
516 439a97cc Gerd Hoffmann
    if (mask & USBSTS_INT) {
517 439a97cc Gerd Hoffmann
        trace_usb_ehci_usbsts("INT", state);
518 439a97cc Gerd Hoffmann
    }
519 439a97cc Gerd Hoffmann
    if (mask & USBSTS_ERRINT) {
520 439a97cc Gerd Hoffmann
        trace_usb_ehci_usbsts("ERRINT", state);
521 439a97cc Gerd Hoffmann
    }
522 439a97cc Gerd Hoffmann
    if (mask & USBSTS_PCD) {
523 439a97cc Gerd Hoffmann
        trace_usb_ehci_usbsts("PCD", state);
524 439a97cc Gerd Hoffmann
    }
525 439a97cc Gerd Hoffmann
    if (mask & USBSTS_FLR) {
526 439a97cc Gerd Hoffmann
        trace_usb_ehci_usbsts("FLR", state);
527 439a97cc Gerd Hoffmann
    }
528 439a97cc Gerd Hoffmann
    if (mask & USBSTS_HSE) {
529 439a97cc Gerd Hoffmann
        trace_usb_ehci_usbsts("HSE", state);
530 439a97cc Gerd Hoffmann
    }
531 439a97cc Gerd Hoffmann
    if (mask & USBSTS_IAA) {
532 439a97cc Gerd Hoffmann
        trace_usb_ehci_usbsts("IAA", state);
533 439a97cc Gerd Hoffmann
    }
534 439a97cc Gerd Hoffmann
535 439a97cc Gerd Hoffmann
    /* status */
536 439a97cc Gerd Hoffmann
    if (mask & USBSTS_HALT) {
537 439a97cc Gerd Hoffmann
        trace_usb_ehci_usbsts("HALT", state);
538 439a97cc Gerd Hoffmann
    }
539 439a97cc Gerd Hoffmann
    if (mask & USBSTS_REC) {
540 439a97cc Gerd Hoffmann
        trace_usb_ehci_usbsts("REC", state);
541 439a97cc Gerd Hoffmann
    }
542 439a97cc Gerd Hoffmann
    if (mask & USBSTS_PSS) {
543 439a97cc Gerd Hoffmann
        trace_usb_ehci_usbsts("PSS", state);
544 439a97cc Gerd Hoffmann
    }
545 439a97cc Gerd Hoffmann
    if (mask & USBSTS_ASS) {
546 439a97cc Gerd Hoffmann
        trace_usb_ehci_usbsts("ASS", state);
547 439a97cc Gerd Hoffmann
    }
548 439a97cc Gerd Hoffmann
}
549 439a97cc Gerd Hoffmann
550 439a97cc Gerd Hoffmann
static inline void ehci_set_usbsts(EHCIState *s, int mask)
551 439a97cc Gerd Hoffmann
{
552 439a97cc Gerd Hoffmann
    if ((s->usbsts & mask) == mask) {
553 439a97cc Gerd Hoffmann
        return;
554 439a97cc Gerd Hoffmann
    }
555 439a97cc Gerd Hoffmann
    ehci_trace_usbsts(mask, 1);
556 439a97cc Gerd Hoffmann
    s->usbsts |= mask;
557 439a97cc Gerd Hoffmann
}
558 439a97cc Gerd Hoffmann
559 439a97cc Gerd Hoffmann
static inline void ehci_clear_usbsts(EHCIState *s, int mask)
560 439a97cc Gerd Hoffmann
{
561 439a97cc Gerd Hoffmann
    if ((s->usbsts & mask) == 0) {
562 439a97cc Gerd Hoffmann
        return;
563 439a97cc Gerd Hoffmann
    }
564 439a97cc Gerd Hoffmann
    ehci_trace_usbsts(mask, 0);
565 439a97cc Gerd Hoffmann
    s->usbsts &= ~mask;
566 439a97cc Gerd Hoffmann
}
567 94527ead Gerd Hoffmann
568 7efc17af Gerd Hoffmann
/* update irq line */
569 7efc17af Gerd Hoffmann
static inline void ehci_update_irq(EHCIState *s)
570 94527ead Gerd Hoffmann
{
571 94527ead Gerd Hoffmann
    int level = 0;
572 94527ead Gerd Hoffmann
573 94527ead Gerd Hoffmann
    if ((s->usbsts & USBINTR_MASK) & s->usbintr) {
574 94527ead Gerd Hoffmann
        level = 1;
575 94527ead Gerd Hoffmann
    }
576 94527ead Gerd Hoffmann
577 7efc17af Gerd Hoffmann
    trace_usb_ehci_irq(level, s->frindex, s->usbsts, s->usbintr);
578 94527ead Gerd Hoffmann
    qemu_set_irq(s->irq, level);
579 94527ead Gerd Hoffmann
}
580 94527ead Gerd Hoffmann
581 7efc17af Gerd Hoffmann
/* flag interrupt condition */
582 7efc17af Gerd Hoffmann
static inline void ehci_raise_irq(EHCIState *s, int intr)
583 94527ead Gerd Hoffmann
{
584 6d3b6d3d Gerd Hoffmann
    if (intr & (USBSTS_PCD | USBSTS_FLR | USBSTS_HSE)) {
585 6d3b6d3d Gerd Hoffmann
        s->usbsts |= intr;
586 6d3b6d3d Gerd Hoffmann
        ehci_update_irq(s);
587 6d3b6d3d Gerd Hoffmann
    } else {
588 6d3b6d3d Gerd Hoffmann
        s->usbsts_pending |= intr;
589 6d3b6d3d Gerd Hoffmann
    }
590 94527ead Gerd Hoffmann
}
591 94527ead Gerd Hoffmann
592 7efc17af Gerd Hoffmann
/*
593 7efc17af Gerd Hoffmann
 * Commit pending interrupts (added via ehci_raise_irq),
594 7efc17af Gerd Hoffmann
 * at the rate allowed by "Interrupt Threshold Control".
595 7efc17af Gerd Hoffmann
 */
596 7efc17af Gerd Hoffmann
static inline void ehci_commit_irq(EHCIState *s)
597 94527ead Gerd Hoffmann
{
598 7efc17af Gerd Hoffmann
    uint32_t itc;
599 7efc17af Gerd Hoffmann
600 94527ead Gerd Hoffmann
    if (!s->usbsts_pending) {
601 94527ead Gerd Hoffmann
        return;
602 94527ead Gerd Hoffmann
    }
603 7efc17af Gerd Hoffmann
    if (s->usbsts_frindex > s->frindex) {
604 7efc17af Gerd Hoffmann
        return;
605 7efc17af Gerd Hoffmann
    }
606 7efc17af Gerd Hoffmann
607 7efc17af Gerd Hoffmann
    itc = (s->usbcmd >> 16) & 0xff;
608 7efc17af Gerd Hoffmann
    s->usbsts |= s->usbsts_pending;
609 94527ead Gerd Hoffmann
    s->usbsts_pending = 0;
610 7efc17af Gerd Hoffmann
    s->usbsts_frindex = s->frindex + itc;
611 7efc17af Gerd Hoffmann
    ehci_update_irq(s);
612 94527ead Gerd Hoffmann
}
613 94527ead Gerd Hoffmann
614 daf25307 Gerd Hoffmann
static void ehci_update_halt(EHCIState *s)
615 daf25307 Gerd Hoffmann
{
616 daf25307 Gerd Hoffmann
    if (s->usbcmd & USBCMD_RUNSTOP) {
617 daf25307 Gerd Hoffmann
        ehci_clear_usbsts(s, USBSTS_HALT);
618 daf25307 Gerd Hoffmann
    } else {
619 daf25307 Gerd Hoffmann
        if (s->astate == EST_INACTIVE && s->pstate == EST_INACTIVE) {
620 daf25307 Gerd Hoffmann
            ehci_set_usbsts(s, USBSTS_HALT);
621 daf25307 Gerd Hoffmann
        }
622 daf25307 Gerd Hoffmann
    }
623 daf25307 Gerd Hoffmann
}
624 daf25307 Gerd Hoffmann
625 26d53979 Gerd Hoffmann
static void ehci_set_state(EHCIState *s, int async, int state)
626 26d53979 Gerd Hoffmann
{
627 26d53979 Gerd Hoffmann
    if (async) {
628 26d53979 Gerd Hoffmann
        trace_usb_ehci_state("async", state2str(state));
629 26d53979 Gerd Hoffmann
        s->astate = state;
630 b53f685d Gerd Hoffmann
        if (s->astate == EST_INACTIVE) {
631 b53f685d Gerd Hoffmann
            ehci_clear_usbsts(s, USBSTS_ASS);
632 daf25307 Gerd Hoffmann
            ehci_update_halt(s);
633 b53f685d Gerd Hoffmann
        } else {
634 b53f685d Gerd Hoffmann
            ehci_set_usbsts(s, USBSTS_ASS);
635 b53f685d Gerd Hoffmann
        }
636 26d53979 Gerd Hoffmann
    } else {
637 26d53979 Gerd Hoffmann
        trace_usb_ehci_state("periodic", state2str(state));
638 26d53979 Gerd Hoffmann
        s->pstate = state;
639 b53f685d Gerd Hoffmann
        if (s->pstate == EST_INACTIVE) {
640 b53f685d Gerd Hoffmann
            ehci_clear_usbsts(s, USBSTS_PSS);
641 daf25307 Gerd Hoffmann
            ehci_update_halt(s);
642 b53f685d Gerd Hoffmann
        } else {
643 b53f685d Gerd Hoffmann
            ehci_set_usbsts(s, USBSTS_PSS);
644 b53f685d Gerd Hoffmann
        }
645 26d53979 Gerd Hoffmann
    }
646 26d53979 Gerd Hoffmann
}
647 26d53979 Gerd Hoffmann
648 26d53979 Gerd Hoffmann
static int ehci_get_state(EHCIState *s, int async)
649 26d53979 Gerd Hoffmann
{
650 26d53979 Gerd Hoffmann
    return async ? s->astate : s->pstate;
651 26d53979 Gerd Hoffmann
}
652 26d53979 Gerd Hoffmann
653 0122f472 Gerd Hoffmann
static void ehci_set_fetch_addr(EHCIState *s, int async, uint32_t addr)
654 0122f472 Gerd Hoffmann
{
655 0122f472 Gerd Hoffmann
    if (async) {
656 0122f472 Gerd Hoffmann
        s->a_fetch_addr = addr;
657 0122f472 Gerd Hoffmann
    } else {
658 0122f472 Gerd Hoffmann
        s->p_fetch_addr = addr;
659 0122f472 Gerd Hoffmann
    }
660 0122f472 Gerd Hoffmann
}
661 0122f472 Gerd Hoffmann
662 0122f472 Gerd Hoffmann
static int ehci_get_fetch_addr(EHCIState *s, int async)
663 0122f472 Gerd Hoffmann
{
664 0122f472 Gerd Hoffmann
    return async ? s->a_fetch_addr : s->p_fetch_addr;
665 0122f472 Gerd Hoffmann
}
666 0122f472 Gerd Hoffmann
667 a8170e5e Avi Kivity
static void ehci_trace_qh(EHCIQueue *q, hwaddr addr, EHCIqh *qh)
668 26d53979 Gerd Hoffmann
{
669 025b168c Gerd Hoffmann
    /* need three here due to argument count limits */
670 025b168c Gerd Hoffmann
    trace_usb_ehci_qh_ptrs(q, addr, qh->next,
671 025b168c Gerd Hoffmann
                           qh->current_qtd, qh->next_qtd, qh->altnext_qtd);
672 025b168c Gerd Hoffmann
    trace_usb_ehci_qh_fields(addr,
673 025b168c Gerd Hoffmann
                             get_field(qh->epchar, QH_EPCHAR_RL),
674 025b168c Gerd Hoffmann
                             get_field(qh->epchar, QH_EPCHAR_MPLEN),
675 025b168c Gerd Hoffmann
                             get_field(qh->epchar, QH_EPCHAR_EPS),
676 025b168c Gerd Hoffmann
                             get_field(qh->epchar, QH_EPCHAR_EP),
677 025b168c Gerd Hoffmann
                             get_field(qh->epchar, QH_EPCHAR_DEVADDR));
678 025b168c Gerd Hoffmann
    trace_usb_ehci_qh_bits(addr,
679 025b168c Gerd Hoffmann
                           (bool)(qh->epchar & QH_EPCHAR_C),
680 025b168c Gerd Hoffmann
                           (bool)(qh->epchar & QH_EPCHAR_H),
681 025b168c Gerd Hoffmann
                           (bool)(qh->epchar & QH_EPCHAR_DTC),
682 025b168c Gerd Hoffmann
                           (bool)(qh->epchar & QH_EPCHAR_I));
683 26d53979 Gerd Hoffmann
}
684 26d53979 Gerd Hoffmann
685 a8170e5e Avi Kivity
static void ehci_trace_qtd(EHCIQueue *q, hwaddr addr, EHCIqtd *qtd)
686 26d53979 Gerd Hoffmann
{
687 025b168c Gerd Hoffmann
    /* need three here due to argument count limits */
688 025b168c Gerd Hoffmann
    trace_usb_ehci_qtd_ptrs(q, addr, qtd->next, qtd->altnext);
689 025b168c Gerd Hoffmann
    trace_usb_ehci_qtd_fields(addr,
690 025b168c Gerd Hoffmann
                              get_field(qtd->token, QTD_TOKEN_TBYTES),
691 025b168c Gerd Hoffmann
                              get_field(qtd->token, QTD_TOKEN_CPAGE),
692 025b168c Gerd Hoffmann
                              get_field(qtd->token, QTD_TOKEN_CERR),
693 025b168c Gerd Hoffmann
                              get_field(qtd->token, QTD_TOKEN_PID));
694 025b168c Gerd Hoffmann
    trace_usb_ehci_qtd_bits(addr,
695 025b168c Gerd Hoffmann
                            (bool)(qtd->token & QTD_TOKEN_IOC),
696 025b168c Gerd Hoffmann
                            (bool)(qtd->token & QTD_TOKEN_ACTIVE),
697 025b168c Gerd Hoffmann
                            (bool)(qtd->token & QTD_TOKEN_HALT),
698 025b168c Gerd Hoffmann
                            (bool)(qtd->token & QTD_TOKEN_BABBLE),
699 025b168c Gerd Hoffmann
                            (bool)(qtd->token & QTD_TOKEN_XACTERR));
700 26d53979 Gerd Hoffmann
}
701 26d53979 Gerd Hoffmann
702 a8170e5e Avi Kivity
static void ehci_trace_itd(EHCIState *s, hwaddr addr, EHCIitd *itd)
703 26d53979 Gerd Hoffmann
{
704 e654887f Gerd Hoffmann
    trace_usb_ehci_itd(addr, itd->next,
705 e654887f Gerd Hoffmann
                       get_field(itd->bufptr[1], ITD_BUFPTR_MAXPKT),
706 e654887f Gerd Hoffmann
                       get_field(itd->bufptr[2], ITD_BUFPTR_MULT),
707 e654887f Gerd Hoffmann
                       get_field(itd->bufptr[0], ITD_BUFPTR_EP),
708 e654887f Gerd Hoffmann
                       get_field(itd->bufptr[0], ITD_BUFPTR_DEVADDR));
709 26d53979 Gerd Hoffmann
}
710 26d53979 Gerd Hoffmann
711 a8170e5e Avi Kivity
static void ehci_trace_sitd(EHCIState *s, hwaddr addr,
712 2fe80192 Gerd Hoffmann
                            EHCIsitd *sitd)
713 2fe80192 Gerd Hoffmann
{
714 2fe80192 Gerd Hoffmann
    trace_usb_ehci_sitd(addr, sitd->next,
715 2fe80192 Gerd Hoffmann
                        (bool)(sitd->results & SITD_RESULTS_ACTIVE));
716 2fe80192 Gerd Hoffmann
}
717 2fe80192 Gerd Hoffmann
718 5c514681 Gerd Hoffmann
static void ehci_trace_guest_bug(EHCIState *s, const char *message)
719 5c514681 Gerd Hoffmann
{
720 5c514681 Gerd Hoffmann
    trace_usb_ehci_guest_bug(message);
721 5c514681 Gerd Hoffmann
    fprintf(stderr, "ehci warning: %s\n", message);
722 5c514681 Gerd Hoffmann
}
723 5c514681 Gerd Hoffmann
724 ec807d12 Gerd Hoffmann
static inline bool ehci_enabled(EHCIState *s)
725 ec807d12 Gerd Hoffmann
{
726 ec807d12 Gerd Hoffmann
    return s->usbcmd & USBCMD_RUNSTOP;
727 ec807d12 Gerd Hoffmann
}
728 ec807d12 Gerd Hoffmann
729 ec807d12 Gerd Hoffmann
static inline bool ehci_async_enabled(EHCIState *s)
730 ec807d12 Gerd Hoffmann
{
731 ec807d12 Gerd Hoffmann
    return ehci_enabled(s) && (s->usbcmd & USBCMD_ASE);
732 ec807d12 Gerd Hoffmann
}
733 ec807d12 Gerd Hoffmann
734 ec807d12 Gerd Hoffmann
static inline bool ehci_periodic_enabled(EHCIState *s)
735 ec807d12 Gerd Hoffmann
{
736 ec807d12 Gerd Hoffmann
    return ehci_enabled(s) && (s->usbcmd & USBCMD_PSE);
737 ec807d12 Gerd Hoffmann
}
738 ec807d12 Gerd Hoffmann
739 eb36a88e Gerd Hoffmann
/* packet management */
740 eb36a88e Gerd Hoffmann
741 eb36a88e Gerd Hoffmann
static EHCIPacket *ehci_alloc_packet(EHCIQueue *q)
742 eb36a88e Gerd Hoffmann
{
743 eb36a88e Gerd Hoffmann
    EHCIPacket *p;
744 eb36a88e Gerd Hoffmann
745 eb36a88e Gerd Hoffmann
    p = g_new0(EHCIPacket, 1);
746 eb36a88e Gerd Hoffmann
    p->queue = q;
747 eb36a88e Gerd Hoffmann
    usb_packet_init(&p->packet);
748 eb36a88e Gerd Hoffmann
    QTAILQ_INSERT_TAIL(&q->packets, p, next);
749 eb36a88e Gerd Hoffmann
    trace_usb_ehci_packet_action(p->queue, p, "alloc");
750 eb36a88e Gerd Hoffmann
    return p;
751 eb36a88e Gerd Hoffmann
}
752 eb36a88e Gerd Hoffmann
753 eb36a88e Gerd Hoffmann
static void ehci_free_packet(EHCIPacket *p)
754 eb36a88e Gerd Hoffmann
{
755 4b63a0df Hans de Goede
    if (p->async == EHCI_ASYNC_FINISHED) {
756 4b63a0df Hans de Goede
        int state = ehci_get_state(p->queue->ehci, p->queue->async);
757 4b63a0df Hans de Goede
        /* This is a normal, but rare condition (cancel racing completion) */
758 4b63a0df Hans de Goede
        fprintf(stderr, "EHCI: Warning packet completed but not processed\n");
759 4b63a0df Hans de Goede
        ehci_state_executing(p->queue);
760 4b63a0df Hans de Goede
        ehci_state_writeback(p->queue);
761 4b63a0df Hans de Goede
        ehci_set_state(p->queue->ehci, p->queue->async, state);
762 4b63a0df Hans de Goede
        /* state_writeback recurses into us with async == EHCI_ASYNC_NONE!! */
763 4b63a0df Hans de Goede
        return;
764 4b63a0df Hans de Goede
    }
765 616789cd Gerd Hoffmann
    trace_usb_ehci_packet_action(p->queue, p, "free");
766 ef5b2344 Hans de Goede
    if (p->async == EHCI_ASYNC_INITIALIZED) {
767 ef5b2344 Hans de Goede
        usb_packet_unmap(&p->packet, &p->sgl);
768 ef5b2344 Hans de Goede
        qemu_sglist_destroy(&p->sgl);
769 ef5b2344 Hans de Goede
    }
770 616789cd Gerd Hoffmann
    if (p->async == EHCI_ASYNC_INFLIGHT) {
771 616789cd Gerd Hoffmann
        usb_cancel_packet(&p->packet);
772 616789cd Gerd Hoffmann
        usb_packet_unmap(&p->packet, &p->sgl);
773 616789cd Gerd Hoffmann
        qemu_sglist_destroy(&p->sgl);
774 616789cd Gerd Hoffmann
    }
775 eb36a88e Gerd Hoffmann
    QTAILQ_REMOVE(&p->queue->packets, p, next);
776 eb36a88e Gerd Hoffmann
    usb_packet_cleanup(&p->packet);
777 eb36a88e Gerd Hoffmann
    g_free(p);
778 eb36a88e Gerd Hoffmann
}
779 eb36a88e Gerd Hoffmann
780 8ac6d699 Gerd Hoffmann
/* queue management */
781 8ac6d699 Gerd Hoffmann
782 8f6d5e26 Gerd Hoffmann
static EHCIQueue *ehci_alloc_queue(EHCIState *ehci, uint32_t addr, int async)
783 8ac6d699 Gerd Hoffmann
{
784 df5d5c5c Hans de Goede
    EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues;
785 8ac6d699 Gerd Hoffmann
    EHCIQueue *q;
786 8ac6d699 Gerd Hoffmann
787 7267c094 Anthony Liguori
    q = g_malloc0(sizeof(*q));
788 8ac6d699 Gerd Hoffmann
    q->ehci = ehci;
789 8f6d5e26 Gerd Hoffmann
    q->qhaddr = addr;
790 ae0138a8 Gerd Hoffmann
    q->async = async;
791 eb36a88e Gerd Hoffmann
    QTAILQ_INIT(&q->packets);
792 df5d5c5c Hans de Goede
    QTAILQ_INSERT_HEAD(head, q, next);
793 8ac6d699 Gerd Hoffmann
    trace_usb_ehci_queue_action(q, "alloc");
794 8ac6d699 Gerd Hoffmann
    return q;
795 8ac6d699 Gerd Hoffmann
}
796 8ac6d699 Gerd Hoffmann
797 5c514681 Gerd Hoffmann
static int ehci_cancel_queue(EHCIQueue *q)
798 c7cdca3b Gerd Hoffmann
{
799 c7cdca3b Gerd Hoffmann
    EHCIPacket *p;
800 5c514681 Gerd Hoffmann
    int packets = 0;
801 c7cdca3b Gerd Hoffmann
802 c7cdca3b Gerd Hoffmann
    p = QTAILQ_FIRST(&q->packets);
803 c7cdca3b Gerd Hoffmann
    if (p == NULL) {
804 5c514681 Gerd Hoffmann
        return 0;
805 c7cdca3b Gerd Hoffmann
    }
806 c7cdca3b Gerd Hoffmann
807 c7cdca3b Gerd Hoffmann
    trace_usb_ehci_queue_action(q, "cancel");
808 c7cdca3b Gerd Hoffmann
    do {
809 c7cdca3b Gerd Hoffmann
        ehci_free_packet(p);
810 5c514681 Gerd Hoffmann
        packets++;
811 c7cdca3b Gerd Hoffmann
    } while ((p = QTAILQ_FIRST(&q->packets)) != NULL);
812 5c514681 Gerd Hoffmann
    return packets;
813 c7cdca3b Gerd Hoffmann
}
814 c7cdca3b Gerd Hoffmann
815 5c514681 Gerd Hoffmann
static int ehci_reset_queue(EHCIQueue *q)
816 dafe31fc Hans de Goede
{
817 5c514681 Gerd Hoffmann
    int packets;
818 5c514681 Gerd Hoffmann
819 dafe31fc Hans de Goede
    trace_usb_ehci_queue_action(q, "reset");
820 5c514681 Gerd Hoffmann
    packets = ehci_cancel_queue(q);
821 dafe31fc Hans de Goede
    q->dev = NULL;
822 dafe31fc Hans de Goede
    q->qtdaddr = 0;
823 5c514681 Gerd Hoffmann
    return packets;
824 dafe31fc Hans de Goede
}
825 dafe31fc Hans de Goede
826 3a8ca08e Hans de Goede
static void ehci_free_queue(EHCIQueue *q, const char *warn)
827 8ac6d699 Gerd Hoffmann
{
828 ae0138a8 Gerd Hoffmann
    EHCIQueueHead *head = q->async ? &q->ehci->aqueues : &q->ehci->pqueues;
829 3a8ca08e Hans de Goede
    int cancelled;
830 eb36a88e Gerd Hoffmann
831 8ac6d699 Gerd Hoffmann
    trace_usb_ehci_queue_action(q, "free");
832 3a8ca08e Hans de Goede
    cancelled = ehci_cancel_queue(q);
833 3a8ca08e Hans de Goede
    if (warn && cancelled > 0) {
834 3a8ca08e Hans de Goede
        ehci_trace_guest_bug(q->ehci, warn);
835 3a8ca08e Hans de Goede
    }
836 df5d5c5c Hans de Goede
    QTAILQ_REMOVE(head, q, next);
837 7267c094 Anthony Liguori
    g_free(q);
838 8ac6d699 Gerd Hoffmann
}
839 8ac6d699 Gerd Hoffmann
840 df5d5c5c Hans de Goede
static EHCIQueue *ehci_find_queue_by_qh(EHCIState *ehci, uint32_t addr,
841 df5d5c5c Hans de Goede
                                        int async)
842 8ac6d699 Gerd Hoffmann
{
843 df5d5c5c Hans de Goede
    EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues;
844 8ac6d699 Gerd Hoffmann
    EHCIQueue *q;
845 8ac6d699 Gerd Hoffmann
846 df5d5c5c Hans de Goede
    QTAILQ_FOREACH(q, head, next) {
847 8ac6d699 Gerd Hoffmann
        if (addr == q->qhaddr) {
848 8ac6d699 Gerd Hoffmann
            return q;
849 8ac6d699 Gerd Hoffmann
        }
850 8ac6d699 Gerd Hoffmann
    }
851 8ac6d699 Gerd Hoffmann
    return NULL;
852 8ac6d699 Gerd Hoffmann
}
853 8ac6d699 Gerd Hoffmann
854 8f5457eb Hans de Goede
static void ehci_queues_rip_unused(EHCIState *ehci, int async)
855 8ac6d699 Gerd Hoffmann
{
856 df5d5c5c Hans de Goede
    EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues;
857 8f5457eb Hans de Goede
    const char *warn = async ? "guest unlinked busy QH" : NULL;
858 3a215326 Gerd Hoffmann
    uint64_t maxage = FRAME_TIMER_NS * ehci->maxframes * 4;
859 8ac6d699 Gerd Hoffmann
    EHCIQueue *q, *tmp;
860 8ac6d699 Gerd Hoffmann
861 df5d5c5c Hans de Goede
    QTAILQ_FOREACH_SAFE(q, head, next, tmp) {
862 8ac6d699 Gerd Hoffmann
        if (q->seen) {
863 8ac6d699 Gerd Hoffmann
            q->seen = 0;
864 adddecb1 Gerd Hoffmann
            q->ts = ehci->last_run_ns;
865 8ac6d699 Gerd Hoffmann
            continue;
866 8ac6d699 Gerd Hoffmann
        }
867 8f5457eb Hans de Goede
        if (ehci->last_run_ns < q->ts + maxage) {
868 8ac6d699 Gerd Hoffmann
            continue;
869 8ac6d699 Gerd Hoffmann
        }
870 3a8ca08e Hans de Goede
        ehci_free_queue(q, warn);
871 8ac6d699 Gerd Hoffmann
    }
872 8ac6d699 Gerd Hoffmann
}
873 8ac6d699 Gerd Hoffmann
874 8f5457eb Hans de Goede
static void ehci_queues_rip_unseen(EHCIState *ehci, int async)
875 8f5457eb Hans de Goede
{
876 8f5457eb Hans de Goede
    EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues;
877 8f5457eb Hans de Goede
    EHCIQueue *q, *tmp;
878 8f5457eb Hans de Goede
879 8f5457eb Hans de Goede
    QTAILQ_FOREACH_SAFE(q, head, next, tmp) {
880 8f5457eb Hans de Goede
        if (!q->seen) {
881 8f5457eb Hans de Goede
            ehci_free_queue(q, NULL);
882 8f5457eb Hans de Goede
        }
883 8f5457eb Hans de Goede
    }
884 8f5457eb Hans de Goede
}
885 8f5457eb Hans de Goede
886 df5d5c5c Hans de Goede
static void ehci_queues_rip_device(EHCIState *ehci, USBDevice *dev, int async)
887 07771f6f Gerd Hoffmann
{
888 df5d5c5c Hans de Goede
    EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues;
889 07771f6f Gerd Hoffmann
    EHCIQueue *q, *tmp;
890 07771f6f Gerd Hoffmann
891 df5d5c5c Hans de Goede
    QTAILQ_FOREACH_SAFE(q, head, next, tmp) {
892 e59928b3 Gerd Hoffmann
        if (q->dev != dev) {
893 07771f6f Gerd Hoffmann
            continue;
894 07771f6f Gerd Hoffmann
        }
895 3a8ca08e Hans de Goede
        ehci_free_queue(q, NULL);
896 07771f6f Gerd Hoffmann
    }
897 07771f6f Gerd Hoffmann
}
898 07771f6f Gerd Hoffmann
899 df5d5c5c Hans de Goede
static void ehci_queues_rip_all(EHCIState *ehci, int async)
900 8ac6d699 Gerd Hoffmann
{
901 df5d5c5c Hans de Goede
    EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues;
902 3a8ca08e Hans de Goede
    const char *warn = async ? "guest stopped busy async schedule" : NULL;
903 8ac6d699 Gerd Hoffmann
    EHCIQueue *q, *tmp;
904 8ac6d699 Gerd Hoffmann
905 df5d5c5c Hans de Goede
    QTAILQ_FOREACH_SAFE(q, head, next, tmp) {
906 3a8ca08e Hans de Goede
        ehci_free_queue(q, warn);
907 8ac6d699 Gerd Hoffmann
    }
908 8ac6d699 Gerd Hoffmann
}
909 8ac6d699 Gerd Hoffmann
910 94527ead Gerd Hoffmann
/* Attach or detach a device on root hub */
911 94527ead Gerd Hoffmann
912 94527ead Gerd Hoffmann
static void ehci_attach(USBPort *port)
913 94527ead Gerd Hoffmann
{
914 94527ead Gerd Hoffmann
    EHCIState *s = port->opaque;
915 94527ead Gerd Hoffmann
    uint32_t *portsc = &s->portsc[port->index];
916 30e9d412 Gerd Hoffmann
    const char *owner = (*portsc & PORTSC_POWNER) ? "comp" : "ehci";
917 94527ead Gerd Hoffmann
918 30e9d412 Gerd Hoffmann
    trace_usb_ehci_port_attach(port->index, owner, port->dev->product_desc);
919 94527ead Gerd Hoffmann
920 a0a3167a Hans de Goede
    if (*portsc & PORTSC_POWNER) {
921 a0a3167a Hans de Goede
        USBPort *companion = s->companion_ports[port->index];
922 a0a3167a Hans de Goede
        companion->dev = port->dev;
923 a0a3167a Hans de Goede
        companion->ops->attach(companion);
924 a0a3167a Hans de Goede
        return;
925 a0a3167a Hans de Goede
    }
926 a0a3167a Hans de Goede
927 94527ead Gerd Hoffmann
    *portsc |= PORTSC_CONNECT;
928 94527ead Gerd Hoffmann
    *portsc |= PORTSC_CSC;
929 94527ead Gerd Hoffmann
930 7efc17af Gerd Hoffmann
    ehci_raise_irq(s, USBSTS_PCD);
931 7efc17af Gerd Hoffmann
    ehci_commit_irq(s);
932 94527ead Gerd Hoffmann
}
933 94527ead Gerd Hoffmann
934 94527ead Gerd Hoffmann
static void ehci_detach(USBPort *port)
935 94527ead Gerd Hoffmann
{
936 94527ead Gerd Hoffmann
    EHCIState *s = port->opaque;
937 94527ead Gerd Hoffmann
    uint32_t *portsc = &s->portsc[port->index];
938 30e9d412 Gerd Hoffmann
    const char *owner = (*portsc & PORTSC_POWNER) ? "comp" : "ehci";
939 94527ead Gerd Hoffmann
940 30e9d412 Gerd Hoffmann
    trace_usb_ehci_port_detach(port->index, owner);
941 94527ead Gerd Hoffmann
942 a0a3167a Hans de Goede
    if (*portsc & PORTSC_POWNER) {
943 a0a3167a Hans de Goede
        USBPort *companion = s->companion_ports[port->index];
944 a0a3167a Hans de Goede
        companion->ops->detach(companion);
945 a0a3167a Hans de Goede
        companion->dev = NULL;
946 f76e1d81 Hans de Goede
        /*
947 f76e1d81 Hans de Goede
         * EHCI spec 4.2.2: "When a disconnect occurs... On the event,
948 f76e1d81 Hans de Goede
         * the port ownership is returned immediately to the EHCI controller."
949 f76e1d81 Hans de Goede
         */
950 f76e1d81 Hans de Goede
        *portsc &= ~PORTSC_POWNER;
951 a0a3167a Hans de Goede
        return;
952 a0a3167a Hans de Goede
    }
953 a0a3167a Hans de Goede
954 df5d5c5c Hans de Goede
    ehci_queues_rip_device(s, port->dev, 0);
955 df5d5c5c Hans de Goede
    ehci_queues_rip_device(s, port->dev, 1);
956 4706ab6c Hans de Goede
957 fbd97532 Hans de Goede
    *portsc &= ~(PORTSC_CONNECT|PORTSC_PED);
958 94527ead Gerd Hoffmann
    *portsc |= PORTSC_CSC;
959 94527ead Gerd Hoffmann
960 7efc17af Gerd Hoffmann
    ehci_raise_irq(s, USBSTS_PCD);
961 7efc17af Gerd Hoffmann
    ehci_commit_irq(s);
962 94527ead Gerd Hoffmann
}
963 94527ead Gerd Hoffmann
964 4706ab6c Hans de Goede
static void ehci_child_detach(USBPort *port, USBDevice *child)
965 4706ab6c Hans de Goede
{
966 4706ab6c Hans de Goede
    EHCIState *s = port->opaque;
967 a0a3167a Hans de Goede
    uint32_t portsc = s->portsc[port->index];
968 a0a3167a Hans de Goede
969 a0a3167a Hans de Goede
    if (portsc & PORTSC_POWNER) {
970 a0a3167a Hans de Goede
        USBPort *companion = s->companion_ports[port->index];
971 a0a3167a Hans de Goede
        companion->ops->child_detach(companion, child);
972 a0a3167a Hans de Goede
        return;
973 a0a3167a Hans de Goede
    }
974 4706ab6c Hans de Goede
975 df5d5c5c Hans de Goede
    ehci_queues_rip_device(s, child, 0);
976 df5d5c5c Hans de Goede
    ehci_queues_rip_device(s, child, 1);
977 4706ab6c Hans de Goede
}
978 4706ab6c Hans de Goede
979 a0a3167a Hans de Goede
static void ehci_wakeup(USBPort *port)
980 a0a3167a Hans de Goede
{
981 a0a3167a Hans de Goede
    EHCIState *s = port->opaque;
982 a0a3167a Hans de Goede
    uint32_t portsc = s->portsc[port->index];
983 a0a3167a Hans de Goede
984 a0a3167a Hans de Goede
    if (portsc & PORTSC_POWNER) {
985 a0a3167a Hans de Goede
        USBPort *companion = s->companion_ports[port->index];
986 a0a3167a Hans de Goede
        if (companion->ops->wakeup) {
987 a0a3167a Hans de Goede
            companion->ops->wakeup(companion);
988 a0a3167a Hans de Goede
        }
989 37952117 Hans de Goede
        return;
990 a0a3167a Hans de Goede
    }
991 37952117 Hans de Goede
992 37952117 Hans de Goede
    qemu_bh_schedule(s->async_bh);
993 a0a3167a Hans de Goede
}
994 a0a3167a Hans de Goede
995 a0a3167a Hans de Goede
static int ehci_register_companion(USBBus *bus, USBPort *ports[],
996 a0a3167a Hans de Goede
                                   uint32_t portcount, uint32_t firstport)
997 a0a3167a Hans de Goede
{
998 a0a3167a Hans de Goede
    EHCIState *s = container_of(bus, EHCIState, bus);
999 a0a3167a Hans de Goede
    uint32_t i;
1000 a0a3167a Hans de Goede
1001 a0a3167a Hans de Goede
    if (firstport + portcount > NB_PORTS) {
1002 a0a3167a Hans de Goede
        qerror_report(QERR_INVALID_PARAMETER_VALUE, "firstport",
1003 a0a3167a Hans de Goede
                      "firstport on masterbus");
1004 a0a3167a Hans de Goede
        error_printf_unless_qmp(
1005 a0a3167a Hans de Goede
            "firstport value of %u makes companion take ports %u - %u, which "
1006 a0a3167a Hans de Goede
            "is outside of the valid range of 0 - %u\n", firstport, firstport,
1007 a0a3167a Hans de Goede
            firstport + portcount - 1, NB_PORTS - 1);
1008 a0a3167a Hans de Goede
        return -1;
1009 a0a3167a Hans de Goede
    }
1010 a0a3167a Hans de Goede
1011 a0a3167a Hans de Goede
    for (i = 0; i < portcount; i++) {
1012 a0a3167a Hans de Goede
        if (s->companion_ports[firstport + i]) {
1013 a0a3167a Hans de Goede
            qerror_report(QERR_INVALID_PARAMETER_VALUE, "masterbus",
1014 a0a3167a Hans de Goede
                          "an USB masterbus");
1015 a0a3167a Hans de Goede
            error_printf_unless_qmp(
1016 a0a3167a Hans de Goede
                "port %u on masterbus %s already has a companion assigned\n",
1017 a0a3167a Hans de Goede
                firstport + i, bus->qbus.name);
1018 a0a3167a Hans de Goede
            return -1;
1019 a0a3167a Hans de Goede
        }
1020 a0a3167a Hans de Goede
    }
1021 a0a3167a Hans de Goede
1022 a0a3167a Hans de Goede
    for (i = 0; i < portcount; i++) {
1023 a0a3167a Hans de Goede
        s->companion_ports[firstport + i] = ports[i];
1024 a0a3167a Hans de Goede
        s->ports[firstport + i].speedmask |=
1025 a0a3167a Hans de Goede
            USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL;
1026 a0a3167a Hans de Goede
        /* Ensure devs attached before the initial reset go to the companion */
1027 a0a3167a Hans de Goede
        s->portsc[firstport + i] = PORTSC_POWNER;
1028 a0a3167a Hans de Goede
    }
1029 a0a3167a Hans de Goede
1030 a0a3167a Hans de Goede
    s->companion_count++;
1031 3e4f910c Gerd Hoffmann
    s->caps[0x05] = (s->companion_count << 4) | portcount;
1032 a0a3167a Hans de Goede
1033 a0a3167a Hans de Goede
    return 0;
1034 a0a3167a Hans de Goede
}
1035 a0a3167a Hans de Goede
1036 828143c6 Gerd Hoffmann
static USBDevice *ehci_find_device(EHCIState *ehci, uint8_t addr)
1037 828143c6 Gerd Hoffmann
{
1038 828143c6 Gerd Hoffmann
    USBDevice *dev;
1039 828143c6 Gerd Hoffmann
    USBPort *port;
1040 828143c6 Gerd Hoffmann
    int i;
1041 828143c6 Gerd Hoffmann
1042 828143c6 Gerd Hoffmann
    for (i = 0; i < NB_PORTS; i++) {
1043 828143c6 Gerd Hoffmann
        port = &ehci->ports[i];
1044 828143c6 Gerd Hoffmann
        if (!(ehci->portsc[i] & PORTSC_PED)) {
1045 828143c6 Gerd Hoffmann
            DPRINTF("Port %d not enabled\n", i);
1046 828143c6 Gerd Hoffmann
            continue;
1047 828143c6 Gerd Hoffmann
        }
1048 828143c6 Gerd Hoffmann
        dev = usb_find_device(port, addr);
1049 828143c6 Gerd Hoffmann
        if (dev != NULL) {
1050 828143c6 Gerd Hoffmann
            return dev;
1051 828143c6 Gerd Hoffmann
        }
1052 828143c6 Gerd Hoffmann
    }
1053 828143c6 Gerd Hoffmann
    return NULL;
1054 828143c6 Gerd Hoffmann
}
1055 828143c6 Gerd Hoffmann
1056 94527ead Gerd Hoffmann
/* 4.1 host controller initialization */
1057 94527ead Gerd Hoffmann
static void ehci_reset(void *opaque)
1058 94527ead Gerd Hoffmann
{
1059 94527ead Gerd Hoffmann
    EHCIState *s = opaque;
1060 94527ead Gerd Hoffmann
    int i;
1061 a0a3167a Hans de Goede
    USBDevice *devs[NB_PORTS];
1062 94527ead Gerd Hoffmann
1063 439a97cc Gerd Hoffmann
    trace_usb_ehci_reset();
1064 94527ead Gerd Hoffmann
1065 a0a3167a Hans de Goede
    /*
1066 a0a3167a Hans de Goede
     * Do the detach before touching portsc, so that it correctly gets send to
1067 a0a3167a Hans de Goede
     * us or to our companion based on PORTSC_POWNER before the reset.
1068 a0a3167a Hans de Goede
     */
1069 a0a3167a Hans de Goede
    for(i = 0; i < NB_PORTS; i++) {
1070 a0a3167a Hans de Goede
        devs[i] = s->ports[i].dev;
1071 891fb2cd Gerd Hoffmann
        if (devs[i] && devs[i]->attached) {
1072 891fb2cd Gerd Hoffmann
            usb_detach(&s->ports[i]);
1073 a0a3167a Hans de Goede
        }
1074 a0a3167a Hans de Goede
    }
1075 a0a3167a Hans de Goede
1076 3e4f910c Gerd Hoffmann
    memset(&s->opreg, 0x00, sizeof(s->opreg));
1077 3e4f910c Gerd Hoffmann
    memset(&s->portsc, 0x00, sizeof(s->portsc));
1078 94527ead Gerd Hoffmann
1079 94527ead Gerd Hoffmann
    s->usbcmd = NB_MAXINTRATE << USBCMD_ITC_SH;
1080 94527ead Gerd Hoffmann
    s->usbsts = USBSTS_HALT;
1081 7efc17af Gerd Hoffmann
    s->usbsts_pending = 0;
1082 7efc17af Gerd Hoffmann
    s->usbsts_frindex = 0;
1083 94527ead Gerd Hoffmann
1084 94527ead Gerd Hoffmann
    s->astate = EST_INACTIVE;
1085 94527ead Gerd Hoffmann
    s->pstate = EST_INACTIVE;
1086 94527ead Gerd Hoffmann
1087 94527ead Gerd Hoffmann
    for(i = 0; i < NB_PORTS; i++) {
1088 a0a3167a Hans de Goede
        if (s->companion_ports[i]) {
1089 a0a3167a Hans de Goede
            s->portsc[i] = PORTSC_POWNER | PORTSC_PPOWER;
1090 a0a3167a Hans de Goede
        } else {
1091 a0a3167a Hans de Goede
            s->portsc[i] = PORTSC_PPOWER;
1092 a0a3167a Hans de Goede
        }
1093 891fb2cd Gerd Hoffmann
        if (devs[i] && devs[i]->attached) {
1094 891fb2cd Gerd Hoffmann
            usb_attach(&s->ports[i]);
1095 d28f4e2d Gerd Hoffmann
            usb_device_reset(devs[i]);
1096 94527ead Gerd Hoffmann
        }
1097 94527ead Gerd Hoffmann
    }
1098 df5d5c5c Hans de Goede
    ehci_queues_rip_all(s, 0);
1099 df5d5c5c Hans de Goede
    ehci_queues_rip_all(s, 1);
1100 81d37739 Gerd Hoffmann
    qemu_del_timer(s->frame_timer);
1101 0fb3e299 Gerd Hoffmann
    qemu_bh_cancel(s->async_bh);
1102 94527ead Gerd Hoffmann
}
1103 94527ead Gerd Hoffmann
1104 a8170e5e Avi Kivity
static uint64_t ehci_caps_read(void *ptr, hwaddr addr,
1105 3e4f910c Gerd Hoffmann
                               unsigned size)
1106 94527ead Gerd Hoffmann
{
1107 94527ead Gerd Hoffmann
    EHCIState *s = ptr;
1108 3e4f910c Gerd Hoffmann
    return s->caps[addr];
1109 94527ead Gerd Hoffmann
}
1110 94527ead Gerd Hoffmann
1111 a8170e5e Avi Kivity
static uint64_t ehci_opreg_read(void *ptr, hwaddr addr,
1112 3e4f910c Gerd Hoffmann
                                unsigned size)
1113 94527ead Gerd Hoffmann
{
1114 94527ead Gerd Hoffmann
    EHCIState *s = ptr;
1115 94527ead Gerd Hoffmann
    uint32_t val;
1116 94527ead Gerd Hoffmann
1117 3e4f910c Gerd Hoffmann
    val = s->opreg[addr >> 2];
1118 3e4f910c Gerd Hoffmann
    trace_usb_ehci_opreg_read(addr + OPREGBASE, addr2str(addr), val);
1119 94527ead Gerd Hoffmann
    return val;
1120 94527ead Gerd Hoffmann
}
1121 94527ead Gerd Hoffmann
1122 a8170e5e Avi Kivity
static uint64_t ehci_port_read(void *ptr, hwaddr addr,
1123 3e4f910c Gerd Hoffmann
                               unsigned size)
1124 94527ead Gerd Hoffmann
{
1125 94527ead Gerd Hoffmann
    EHCIState *s = ptr;
1126 94527ead Gerd Hoffmann
    uint32_t val;
1127 94527ead Gerd Hoffmann
1128 3e4f910c Gerd Hoffmann
    val = s->portsc[addr >> 2];
1129 3e4f910c Gerd Hoffmann
    trace_usb_ehci_portsc_read(addr + PORTSC_BEGIN, addr >> 2, val);
1130 94527ead Gerd Hoffmann
    return val;
1131 94527ead Gerd Hoffmann
}
1132 94527ead Gerd Hoffmann
1133 a0a3167a Hans de Goede
static void handle_port_owner_write(EHCIState *s, int port, uint32_t owner)
1134 a0a3167a Hans de Goede
{
1135 a0a3167a Hans de Goede
    USBDevice *dev = s->ports[port].dev;
1136 a0a3167a Hans de Goede
    uint32_t *portsc = &s->portsc[port];
1137 a0a3167a Hans de Goede
    uint32_t orig;
1138 a0a3167a Hans de Goede
1139 a0a3167a Hans de Goede
    if (s->companion_ports[port] == NULL)
1140 a0a3167a Hans de Goede
        return;
1141 a0a3167a Hans de Goede
1142 a0a3167a Hans de Goede
    owner = owner & PORTSC_POWNER;
1143 a0a3167a Hans de Goede
    orig  = *portsc & PORTSC_POWNER;
1144 a0a3167a Hans de Goede
1145 a0a3167a Hans de Goede
    if (!(owner ^ orig)) {
1146 a0a3167a Hans de Goede
        return;
1147 a0a3167a Hans de Goede
    }
1148 a0a3167a Hans de Goede
1149 891fb2cd Gerd Hoffmann
    if (dev && dev->attached) {
1150 891fb2cd Gerd Hoffmann
        usb_detach(&s->ports[port]);
1151 a0a3167a Hans de Goede
    }
1152 a0a3167a Hans de Goede
1153 a0a3167a Hans de Goede
    *portsc &= ~PORTSC_POWNER;
1154 a0a3167a Hans de Goede
    *portsc |= owner;
1155 a0a3167a Hans de Goede
1156 891fb2cd Gerd Hoffmann
    if (dev && dev->attached) {
1157 891fb2cd Gerd Hoffmann
        usb_attach(&s->ports[port]);
1158 a0a3167a Hans de Goede
    }
1159 a0a3167a Hans de Goede
}
1160 a0a3167a Hans de Goede
1161 a8170e5e Avi Kivity
static void ehci_port_write(void *ptr, hwaddr addr,
1162 3e4f910c Gerd Hoffmann
                            uint64_t val, unsigned size)
1163 94527ead Gerd Hoffmann
{
1164 3e4f910c Gerd Hoffmann
    EHCIState *s = ptr;
1165 3e4f910c Gerd Hoffmann
    int port = addr >> 2;
1166 94527ead Gerd Hoffmann
    uint32_t *portsc = &s->portsc[port];
1167 3e4f910c Gerd Hoffmann
    uint32_t old = *portsc;
1168 94527ead Gerd Hoffmann
    USBDevice *dev = s->ports[port].dev;
1169 94527ead Gerd Hoffmann
1170 3e4f910c Gerd Hoffmann
    trace_usb_ehci_portsc_write(addr + PORTSC_BEGIN, addr >> 2, val);
1171 3e4f910c Gerd Hoffmann
1172 fbd97532 Hans de Goede
    /* Clear rwc bits */
1173 fbd97532 Hans de Goede
    *portsc &= ~(val & PORTSC_RWC_MASK);
1174 fbd97532 Hans de Goede
    /* The guest may clear, but not set the PED bit */
1175 fbd97532 Hans de Goede
    *portsc &= val | ~PORTSC_PED;
1176 a0a3167a Hans de Goede
    /* POWNER is masked out by RO_MASK as it is RO when we've no companion */
1177 a0a3167a Hans de Goede
    handle_port_owner_write(s, port, val);
1178 a0a3167a Hans de Goede
    /* And finally apply RO_MASK */
1179 94527ead Gerd Hoffmann
    val &= PORTSC_RO_MASK;
1180 94527ead Gerd Hoffmann
1181 94527ead Gerd Hoffmann
    if ((val & PORTSC_PRESET) && !(*portsc & PORTSC_PRESET)) {
1182 dcbd0b5c Gerd Hoffmann
        trace_usb_ehci_port_reset(port, 1);
1183 94527ead Gerd Hoffmann
    }
1184 94527ead Gerd Hoffmann
1185 94527ead Gerd Hoffmann
    if (!(val & PORTSC_PRESET) &&(*portsc & PORTSC_PRESET)) {
1186 dcbd0b5c Gerd Hoffmann
        trace_usb_ehci_port_reset(port, 0);
1187 891fb2cd Gerd Hoffmann
        if (dev && dev->attached) {
1188 d28f4e2d Gerd Hoffmann
            usb_port_reset(&s->ports[port]);
1189 94527ead Gerd Hoffmann
            *portsc &= ~PORTSC_CSC;
1190 94527ead Gerd Hoffmann
        }
1191 94527ead Gerd Hoffmann
1192 fbd97532 Hans de Goede
        /*
1193 fbd97532 Hans de Goede
         *  Table 2.16 Set the enable bit(and enable bit change) to indicate
1194 94527ead Gerd Hoffmann
         *  to SW that this port has a high speed device attached
1195 94527ead Gerd Hoffmann
         */
1196 891fb2cd Gerd Hoffmann
        if (dev && dev->attached && (dev->speedmask & USB_SPEED_MASK_HIGH)) {
1197 fbd97532 Hans de Goede
            val |= PORTSC_PED;
1198 fbd97532 Hans de Goede
        }
1199 94527ead Gerd Hoffmann
    }
1200 94527ead Gerd Hoffmann
1201 94527ead Gerd Hoffmann
    *portsc &= ~PORTSC_RO_MASK;
1202 94527ead Gerd Hoffmann
    *portsc |= val;
1203 3e4f910c Gerd Hoffmann
    trace_usb_ehci_portsc_change(addr + PORTSC_BEGIN, addr >> 2, *portsc, old);
1204 94527ead Gerd Hoffmann
}
1205 94527ead Gerd Hoffmann
1206 a8170e5e Avi Kivity
static void ehci_opreg_write(void *ptr, hwaddr addr,
1207 3e4f910c Gerd Hoffmann
                             uint64_t val, unsigned size)
1208 94527ead Gerd Hoffmann
{
1209 94527ead Gerd Hoffmann
    EHCIState *s = ptr;
1210 3e4f910c Gerd Hoffmann
    uint32_t *mmio = s->opreg + (addr >> 2);
1211 c4f8e211 Gerd Hoffmann
    uint32_t old = *mmio;
1212 94527ead Gerd Hoffmann
    int i;
1213 439a97cc Gerd Hoffmann
1214 3e4f910c Gerd Hoffmann
    trace_usb_ehci_opreg_write(addr + OPREGBASE, addr2str(addr), val);
1215 94527ead Gerd Hoffmann
1216 3e4f910c Gerd Hoffmann
    switch (addr + OPREGBASE) {
1217 94527ead Gerd Hoffmann
    case USBCMD:
1218 7046530c Gerd Hoffmann
        if (val & USBCMD_HCRESET) {
1219 7046530c Gerd Hoffmann
            ehci_reset(s);
1220 7046530c Gerd Hoffmann
            val = s->usbcmd;
1221 7046530c Gerd Hoffmann
            break;
1222 7046530c Gerd Hoffmann
        }
1223 7046530c Gerd Hoffmann
1224 47d073cc Hans de Goede
        /* not supporting dynamic frame list size at the moment */
1225 47d073cc Hans de Goede
        if ((val & USBCMD_FLS) && !(s->usbcmd & USBCMD_FLS)) {
1226 47d073cc Hans de Goede
            fprintf(stderr, "attempt to set frame list size -- value %d\n",
1227 3e4f910c Gerd Hoffmann
                    (int)val & USBCMD_FLS);
1228 47d073cc Hans de Goede
            val &= ~USBCMD_FLS;
1229 47d073cc Hans de Goede
        }
1230 47d073cc Hans de Goede
1231 a1c3e4b8 Hans de Goede
        if (val & USBCMD_IAAD) {
1232 a1c3e4b8 Hans de Goede
            /*
1233 a1c3e4b8 Hans de Goede
             * Process IAAD immediately, otherwise the Linux IAAD watchdog may
1234 a1c3e4b8 Hans de Goede
             * trigger and re-use a qh without us seeing the unlink.
1235 a1c3e4b8 Hans de Goede
             */
1236 a1c3e4b8 Hans de Goede
            s->async_stepdown = 0;
1237 a1c3e4b8 Hans de Goede
            qemu_bh_schedule(s->async_bh);
1238 1defcbd1 Gerd Hoffmann
            trace_usb_ehci_doorbell_ring();
1239 a1c3e4b8 Hans de Goede
        }
1240 a1c3e4b8 Hans de Goede
1241 daf25307 Gerd Hoffmann
        if (((USBCMD_RUNSTOP | USBCMD_PSE | USBCMD_ASE) & val) !=
1242 daf25307 Gerd Hoffmann
            ((USBCMD_RUNSTOP | USBCMD_PSE | USBCMD_ASE) & s->usbcmd)) {
1243 3a215326 Gerd Hoffmann
            if (s->pstate == EST_INACTIVE) {
1244 daf25307 Gerd Hoffmann
                SET_LAST_RUN_CLOCK(s);
1245 daf25307 Gerd Hoffmann
            }
1246 47d073cc Hans de Goede
            s->usbcmd = val; /* Set usbcmd for ehci_update_halt() */
1247 daf25307 Gerd Hoffmann
            ehci_update_halt(s);
1248 3a215326 Gerd Hoffmann
            s->async_stepdown = 0;
1249 0262f65a Hans de Goede
            qemu_bh_schedule(s->async_bh);
1250 94527ead Gerd Hoffmann
        }
1251 94527ead Gerd Hoffmann
        break;
1252 94527ead Gerd Hoffmann
1253 94527ead Gerd Hoffmann
    case USBSTS:
1254 a31f0531 Jim Meyering
        val &= USBSTS_RO_MASK;              // bits 6 through 31 are RO
1255 a31f0531 Jim Meyering
        ehci_clear_usbsts(s, val);          // bits 0 through 5 are R/WC
1256 439a97cc Gerd Hoffmann
        val = s->usbsts;
1257 7efc17af Gerd Hoffmann
        ehci_update_irq(s);
1258 94527ead Gerd Hoffmann
        break;
1259 94527ead Gerd Hoffmann
1260 94527ead Gerd Hoffmann
    case USBINTR:
1261 94527ead Gerd Hoffmann
        val &= USBINTR_MASK;
1262 94527ead Gerd Hoffmann
        break;
1263 94527ead Gerd Hoffmann
1264 8a771f77 Hans de Goede
    case FRINDEX:
1265 8a771f77 Hans de Goede
        val &= 0x00003ff8; /* frindex is 14bits and always a multiple of 8 */
1266 8a771f77 Hans de Goede
        break;
1267 8a771f77 Hans de Goede
1268 94527ead Gerd Hoffmann
    case CONFIGFLAG:
1269 94527ead Gerd Hoffmann
        val &= 0x1;
1270 94527ead Gerd Hoffmann
        if (val) {
1271 94527ead Gerd Hoffmann
            for(i = 0; i < NB_PORTS; i++)
1272 a0a3167a Hans de Goede
                handle_port_owner_write(s, i, 0);
1273 94527ead Gerd Hoffmann
        }
1274 94527ead Gerd Hoffmann
        break;
1275 94527ead Gerd Hoffmann
1276 94527ead Gerd Hoffmann
    case PERIODICLISTBASE:
1277 ec807d12 Gerd Hoffmann
        if (ehci_periodic_enabled(s)) {
1278 94527ead Gerd Hoffmann
            fprintf(stderr,
1279 94527ead Gerd Hoffmann
              "ehci: PERIODIC list base register set while periodic schedule\n"
1280 94527ead Gerd Hoffmann
              "      is enabled and HC is enabled\n");
1281 94527ead Gerd Hoffmann
        }
1282 94527ead Gerd Hoffmann
        break;
1283 94527ead Gerd Hoffmann
1284 94527ead Gerd Hoffmann
    case ASYNCLISTADDR:
1285 ec807d12 Gerd Hoffmann
        if (ehci_async_enabled(s)) {
1286 94527ead Gerd Hoffmann
            fprintf(stderr,
1287 94527ead Gerd Hoffmann
              "ehci: ASYNC list address register set while async schedule\n"
1288 94527ead Gerd Hoffmann
              "      is enabled and HC is enabled\n");
1289 94527ead Gerd Hoffmann
        }
1290 94527ead Gerd Hoffmann
        break;
1291 94527ead Gerd Hoffmann
    }
1292 94527ead Gerd Hoffmann
1293 c4f8e211 Gerd Hoffmann
    *mmio = val;
1294 3e4f910c Gerd Hoffmann
    trace_usb_ehci_opreg_change(addr + OPREGBASE, addr2str(addr), *mmio, old);
1295 94527ead Gerd Hoffmann
}
1296 94527ead Gerd Hoffmann
1297 94527ead Gerd Hoffmann
1298 94527ead Gerd Hoffmann
// TODO : Put in common header file, duplication from usb-ohci.c
1299 94527ead Gerd Hoffmann
1300 94527ead Gerd Hoffmann
/* Get an array of dwords from main memory */
1301 68d55358 David Gibson
static inline int get_dwords(EHCIState *ehci, uint32_t addr,
1302 68d55358 David Gibson
                             uint32_t *buf, int num)
1303 94527ead Gerd Hoffmann
{
1304 94527ead Gerd Hoffmann
    int i;
1305 94527ead Gerd Hoffmann
1306 94527ead Gerd Hoffmann
    for(i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
1307 4bf80119 David Gibson
        pci_dma_read(&ehci->dev, addr, buf, sizeof(*buf));
1308 94527ead Gerd Hoffmann
        *buf = le32_to_cpu(*buf);
1309 94527ead Gerd Hoffmann
    }
1310 94527ead Gerd Hoffmann
1311 94527ead Gerd Hoffmann
    return 1;
1312 94527ead Gerd Hoffmann
}
1313 94527ead Gerd Hoffmann
1314 94527ead Gerd Hoffmann
/* Put an array of dwords in to main memory */
1315 68d55358 David Gibson
static inline int put_dwords(EHCIState *ehci, uint32_t addr,
1316 68d55358 David Gibson
                             uint32_t *buf, int num)
1317 94527ead Gerd Hoffmann
{
1318 94527ead Gerd Hoffmann
    int i;
1319 94527ead Gerd Hoffmann
1320 94527ead Gerd Hoffmann
    for(i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
1321 94527ead Gerd Hoffmann
        uint32_t tmp = cpu_to_le32(*buf);
1322 4bf80119 David Gibson
        pci_dma_write(&ehci->dev, addr, &tmp, sizeof(tmp));
1323 94527ead Gerd Hoffmann
    }
1324 94527ead Gerd Hoffmann
1325 94527ead Gerd Hoffmann
    return 1;
1326 94527ead Gerd Hoffmann
}
1327 94527ead Gerd Hoffmann
1328 a5e0139a Gerd Hoffmann
/*
1329 a5e0139a Gerd Hoffmann
 *  Write the qh back to guest physical memory.  This step isn't
1330 a5e0139a Gerd Hoffmann
 *  in the EHCI spec but we need to do it since we don't share
1331 a5e0139a Gerd Hoffmann
 *  physical memory with our guest VM.
1332 a5e0139a Gerd Hoffmann
 *
1333 a5e0139a Gerd Hoffmann
 *  The first three dwords are read-only for the EHCI, so skip them
1334 a5e0139a Gerd Hoffmann
 *  when writing back the qh.
1335 a5e0139a Gerd Hoffmann
 */
1336 a5e0139a Gerd Hoffmann
static void ehci_flush_qh(EHCIQueue *q)
1337 a5e0139a Gerd Hoffmann
{
1338 a5e0139a Gerd Hoffmann
    uint32_t *qh = (uint32_t *) &q->qh;
1339 a5e0139a Gerd Hoffmann
    uint32_t dwords = sizeof(EHCIqh) >> 2;
1340 a5e0139a Gerd Hoffmann
    uint32_t addr = NLPTR_GET(q->qhaddr);
1341 a5e0139a Gerd Hoffmann
1342 a5e0139a Gerd Hoffmann
    put_dwords(q->ehci, addr + 3 * sizeof(uint32_t), qh + 3, dwords - 3);
1343 a5e0139a Gerd Hoffmann
}
1344 a5e0139a Gerd Hoffmann
1345 94527ead Gerd Hoffmann
// 4.10.2
1346 94527ead Gerd Hoffmann
1347 0122f472 Gerd Hoffmann
static int ehci_qh_do_overlay(EHCIQueue *q)
1348 94527ead Gerd Hoffmann
{
1349 eb36a88e Gerd Hoffmann
    EHCIPacket *p = QTAILQ_FIRST(&q->packets);
1350 94527ead Gerd Hoffmann
    int i;
1351 94527ead Gerd Hoffmann
    int dtoggle;
1352 94527ead Gerd Hoffmann
    int ping;
1353 94527ead Gerd Hoffmann
    int eps;
1354 94527ead Gerd Hoffmann
    int reload;
1355 94527ead Gerd Hoffmann
1356 eb36a88e Gerd Hoffmann
    assert(p != NULL);
1357 eb36a88e Gerd Hoffmann
    assert(p->qtdaddr == q->qtdaddr);
1358 eb36a88e Gerd Hoffmann
1359 94527ead Gerd Hoffmann
    // remember values in fields to preserve in qh after overlay
1360 94527ead Gerd Hoffmann
1361 0122f472 Gerd Hoffmann
    dtoggle = q->qh.token & QTD_TOKEN_DTOGGLE;
1362 0122f472 Gerd Hoffmann
    ping    = q->qh.token & QTD_TOKEN_PING;
1363 94527ead Gerd Hoffmann
1364 eb36a88e Gerd Hoffmann
    q->qh.current_qtd = p->qtdaddr;
1365 eb36a88e Gerd Hoffmann
    q->qh.next_qtd    = p->qtd.next;
1366 eb36a88e Gerd Hoffmann
    q->qh.altnext_qtd = p->qtd.altnext;
1367 eb36a88e Gerd Hoffmann
    q->qh.token       = p->qtd.token;
1368 94527ead Gerd Hoffmann
1369 94527ead Gerd Hoffmann
1370 0122f472 Gerd Hoffmann
    eps = get_field(q->qh.epchar, QH_EPCHAR_EPS);
1371 94527ead Gerd Hoffmann
    if (eps == EHCI_QH_EPS_HIGH) {
1372 0122f472 Gerd Hoffmann
        q->qh.token &= ~QTD_TOKEN_PING;
1373 0122f472 Gerd Hoffmann
        q->qh.token |= ping;
1374 94527ead Gerd Hoffmann
    }
1375 94527ead Gerd Hoffmann
1376 0122f472 Gerd Hoffmann
    reload = get_field(q->qh.epchar, QH_EPCHAR_RL);
1377 0122f472 Gerd Hoffmann
    set_field(&q->qh.altnext_qtd, reload, QH_ALTNEXT_NAKCNT);
1378 94527ead Gerd Hoffmann
1379 94527ead Gerd Hoffmann
    for (i = 0; i < 5; i++) {
1380 eb36a88e Gerd Hoffmann
        q->qh.bufptr[i] = p->qtd.bufptr[i];
1381 94527ead Gerd Hoffmann
    }
1382 94527ead Gerd Hoffmann
1383 0122f472 Gerd Hoffmann
    if (!(q->qh.epchar & QH_EPCHAR_DTC)) {
1384 94527ead Gerd Hoffmann
        // preserve QH DT bit
1385 0122f472 Gerd Hoffmann
        q->qh.token &= ~QTD_TOKEN_DTOGGLE;
1386 0122f472 Gerd Hoffmann
        q->qh.token |= dtoggle;
1387 94527ead Gerd Hoffmann
    }
1388 94527ead Gerd Hoffmann
1389 0122f472 Gerd Hoffmann
    q->qh.bufptr[1] &= ~BUFPTR_CPROGMASK_MASK;
1390 0122f472 Gerd Hoffmann
    q->qh.bufptr[2] &= ~BUFPTR_FRAMETAG_MASK;
1391 94527ead Gerd Hoffmann
1392 a5e0139a Gerd Hoffmann
    ehci_flush_qh(q);
1393 94527ead Gerd Hoffmann
1394 94527ead Gerd Hoffmann
    return 0;
1395 94527ead Gerd Hoffmann
}
1396 94527ead Gerd Hoffmann
1397 eb36a88e Gerd Hoffmann
static int ehci_init_transfer(EHCIPacket *p)
1398 94527ead Gerd Hoffmann
{
1399 0ce668bc Gerd Hoffmann
    uint32_t cpage, offset, bytes, plen;
1400 68d55358 David Gibson
    dma_addr_t page;
1401 94527ead Gerd Hoffmann
1402 eb36a88e Gerd Hoffmann
    cpage  = get_field(p->qtd.token, QTD_TOKEN_CPAGE);
1403 eb36a88e Gerd Hoffmann
    bytes  = get_field(p->qtd.token, QTD_TOKEN_TBYTES);
1404 eb36a88e Gerd Hoffmann
    offset = p->qtd.bufptr[0] & ~QTD_BUFPTR_MASK;
1405 eb36a88e Gerd Hoffmann
    pci_dma_sglist_init(&p->sgl, &p->queue->ehci->dev, 5);
1406 94527ead Gerd Hoffmann
1407 0ce668bc Gerd Hoffmann
    while (bytes > 0) {
1408 0ce668bc Gerd Hoffmann
        if (cpage > 4) {
1409 0ce668bc Gerd Hoffmann
            fprintf(stderr, "cpage out of range (%d)\n", cpage);
1410 0ce668bc Gerd Hoffmann
            return USB_RET_PROCERR;
1411 0ce668bc Gerd Hoffmann
        }
1412 94527ead Gerd Hoffmann
1413 eb36a88e Gerd Hoffmann
        page  = p->qtd.bufptr[cpage] & QTD_BUFPTR_MASK;
1414 0ce668bc Gerd Hoffmann
        page += offset;
1415 0ce668bc Gerd Hoffmann
        plen  = bytes;
1416 0ce668bc Gerd Hoffmann
        if (plen > 4096 - offset) {
1417 0ce668bc Gerd Hoffmann
            plen = 4096 - offset;
1418 0ce668bc Gerd Hoffmann
            offset = 0;
1419 0ce668bc Gerd Hoffmann
            cpage++;
1420 94527ead Gerd Hoffmann
        }
1421 94527ead Gerd Hoffmann
1422 eb36a88e Gerd Hoffmann
        qemu_sglist_add(&p->sgl, page, plen);
1423 0ce668bc Gerd Hoffmann
        bytes -= plen;
1424 0ce668bc Gerd Hoffmann
    }
1425 0ce668bc Gerd Hoffmann
    return 0;
1426 0ce668bc Gerd Hoffmann
}
1427 94527ead Gerd Hoffmann
1428 0ce668bc Gerd Hoffmann
static void ehci_finish_transfer(EHCIQueue *q, int status)
1429 0ce668bc Gerd Hoffmann
{
1430 0ce668bc Gerd Hoffmann
    uint32_t cpage, offset;
1431 94527ead Gerd Hoffmann
1432 0ce668bc Gerd Hoffmann
    if (status > 0) {
1433 0ce668bc Gerd Hoffmann
        /* update cpage & offset */
1434 0ce668bc Gerd Hoffmann
        cpage  = get_field(q->qh.token, QTD_TOKEN_CPAGE);
1435 0ce668bc Gerd Hoffmann
        offset = q->qh.bufptr[0] & ~QTD_BUFPTR_MASK;
1436 94527ead Gerd Hoffmann
1437 0ce668bc Gerd Hoffmann
        offset += status;
1438 0ce668bc Gerd Hoffmann
        cpage  += offset >> QTD_BUFPTR_SH;
1439 0ce668bc Gerd Hoffmann
        offset &= ~QTD_BUFPTR_MASK;
1440 94527ead Gerd Hoffmann
1441 0ce668bc Gerd Hoffmann
        set_field(&q->qh.token, cpage, QTD_TOKEN_CPAGE);
1442 0ce668bc Gerd Hoffmann
        q->qh.bufptr[0] &= QTD_BUFPTR_MASK;
1443 0ce668bc Gerd Hoffmann
        q->qh.bufptr[0] |= offset;
1444 0ce668bc Gerd Hoffmann
    }
1445 94527ead Gerd Hoffmann
}
1446 94527ead Gerd Hoffmann
1447 d47e59b8 Hans de Goede
static void ehci_async_complete_packet(USBPort *port, USBPacket *packet)
1448 94527ead Gerd Hoffmann
{
1449 eb36a88e Gerd Hoffmann
    EHCIPacket *p;
1450 a0a3167a Hans de Goede
    EHCIState *s = port->opaque;
1451 a0a3167a Hans de Goede
    uint32_t portsc = s->portsc[port->index];
1452 a0a3167a Hans de Goede
1453 a0a3167a Hans de Goede
    if (portsc & PORTSC_POWNER) {
1454 a0a3167a Hans de Goede
        USBPort *companion = s->companion_ports[port->index];
1455 a0a3167a Hans de Goede
        companion->ops->complete(companion, packet);
1456 a0a3167a Hans de Goede
        return;
1457 a0a3167a Hans de Goede
    }
1458 94527ead Gerd Hoffmann
1459 eb36a88e Gerd Hoffmann
    p = container_of(packet, EHCIPacket, packet);
1460 eb36a88e Gerd Hoffmann
    assert(p->async == EHCI_ASYNC_INFLIGHT);
1461 0cae7b1a Hans de Goede
1462 0cae7b1a Hans de Goede
    if (packet->result == USB_RET_REMOVE_FROM_QUEUE) {
1463 0cae7b1a Hans de Goede
        trace_usb_ehci_packet_action(p->queue, p, "remove");
1464 0cae7b1a Hans de Goede
        ehci_free_packet(p);
1465 0cae7b1a Hans de Goede
        return;
1466 0cae7b1a Hans de Goede
    }
1467 0cae7b1a Hans de Goede
1468 0cae7b1a Hans de Goede
    trace_usb_ehci_packet_action(p->queue, p, "wakeup");
1469 eb36a88e Gerd Hoffmann
    p->async = EHCI_ASYNC_FINISHED;
1470 eb36a88e Gerd Hoffmann
    p->usb_status = packet->result;
1471 ae710b99 Gerd Hoffmann
1472 ae710b99 Gerd Hoffmann
    if (p->queue->async) {
1473 ae710b99 Gerd Hoffmann
        qemu_bh_schedule(p->queue->ehci->async_bh);
1474 ae710b99 Gerd Hoffmann
    }
1475 94527ead Gerd Hoffmann
}
1476 94527ead Gerd Hoffmann
1477 0122f472 Gerd Hoffmann
static void ehci_execute_complete(EHCIQueue *q)
1478 94527ead Gerd Hoffmann
{
1479 eb36a88e Gerd Hoffmann
    EHCIPacket *p = QTAILQ_FIRST(&q->packets);
1480 eb36a88e Gerd Hoffmann
1481 eb36a88e Gerd Hoffmann
    assert(p != NULL);
1482 eb36a88e Gerd Hoffmann
    assert(p->qtdaddr == q->qtdaddr);
1483 ef5b2344 Hans de Goede
    assert(p->async == EHCI_ASYNC_INITIALIZED ||
1484 ef5b2344 Hans de Goede
           p->async == EHCI_ASYNC_FINISHED);
1485 94527ead Gerd Hoffmann
1486 94527ead Gerd Hoffmann
    DPRINTF("execute_complete: qhaddr 0x%x, next %x, qtdaddr 0x%x, status %d\n",
1487 0122f472 Gerd Hoffmann
            q->qhaddr, q->qh.next, q->qtdaddr, q->usb_status);
1488 94527ead Gerd Hoffmann
1489 eb36a88e Gerd Hoffmann
    if (p->usb_status < 0) {
1490 eb36a88e Gerd Hoffmann
        switch (p->usb_status) {
1491 d61000a8 Hans de Goede
        case USB_RET_IOERROR:
1492 94527ead Gerd Hoffmann
        case USB_RET_NODEV:
1493 d2bd525f Gerd Hoffmann
            q->qh.token |= (QTD_TOKEN_HALT | QTD_TOKEN_XACTERR);
1494 dd54cfe0 Hans de Goede
            set_field(&q->qh.token, 0, QTD_TOKEN_CERR);
1495 7efc17af Gerd Hoffmann
            ehci_raise_irq(q->ehci, USBSTS_ERRINT);
1496 94527ead Gerd Hoffmann
            break;
1497 94527ead Gerd Hoffmann
        case USB_RET_STALL:
1498 0122f472 Gerd Hoffmann
            q->qh.token |= QTD_TOKEN_HALT;
1499 7efc17af Gerd Hoffmann
            ehci_raise_irq(q->ehci, USBSTS_ERRINT);
1500 94527ead Gerd Hoffmann
            break;
1501 94527ead Gerd Hoffmann
        case USB_RET_NAK:
1502 553a6a59 Hans de Goede
            set_field(&q->qh.altnext_qtd, 0, QH_ALTNEXT_NAKCNT);
1503 553a6a59 Hans de Goede
            return; /* We're not done yet with this transaction */
1504 94527ead Gerd Hoffmann
        case USB_RET_BABBLE:
1505 d2bd525f Gerd Hoffmann
            q->qh.token |= (QTD_TOKEN_HALT | QTD_TOKEN_BABBLE);
1506 7efc17af Gerd Hoffmann
            ehci_raise_irq(q->ehci, USBSTS_ERRINT);
1507 94527ead Gerd Hoffmann
            break;
1508 94527ead Gerd Hoffmann
        default:
1509 0122f472 Gerd Hoffmann
            /* should not be triggerable */
1510 eb36a88e Gerd Hoffmann
            fprintf(stderr, "USB invalid response %d\n", p->usb_status);
1511 0122f472 Gerd Hoffmann
            assert(0);
1512 94527ead Gerd Hoffmann
            break;
1513 94527ead Gerd Hoffmann
        }
1514 94527ead Gerd Hoffmann
    } else {
1515 94527ead Gerd Hoffmann
        // TODO check 4.12 for splits
1516 549a3c3d Hans de Goede
        uint32_t tbytes = get_field(q->qh.token, QTD_TOKEN_TBYTES);
1517 94527ead Gerd Hoffmann
1518 549a3c3d Hans de Goede
        if (tbytes && p->pid == USB_TOKEN_IN) {
1519 549a3c3d Hans de Goede
            tbytes -= p->usb_status;
1520 cf08a8a1 Hans de Goede
            if (tbytes) {
1521 cf08a8a1 Hans de Goede
                /* 4.15.1.2 must raise int on a short input packet */
1522 cf08a8a1 Hans de Goede
                ehci_raise_irq(q->ehci, USBSTS_INT);
1523 cf08a8a1 Hans de Goede
            }
1524 94527ead Gerd Hoffmann
        } else {
1525 549a3c3d Hans de Goede
            tbytes = 0;
1526 94527ead Gerd Hoffmann
        }
1527 94527ead Gerd Hoffmann
1528 549a3c3d Hans de Goede
        DPRINTF("updating tbytes to %d\n", tbytes);
1529 549a3c3d Hans de Goede
        set_field(&q->qh.token, tbytes, QTD_TOKEN_TBYTES);
1530 94527ead Gerd Hoffmann
    }
1531 eb36a88e Gerd Hoffmann
    ehci_finish_transfer(q, p->usb_status);
1532 e2f89926 David Gibson
    usb_packet_unmap(&p->packet, &p->sgl);
1533 eb36a88e Gerd Hoffmann
    qemu_sglist_destroy(&p->sgl);
1534 ef5b2344 Hans de Goede
    p->async = EHCI_ASYNC_NONE;
1535 94527ead Gerd Hoffmann
1536 0122f472 Gerd Hoffmann
    q->qh.token ^= QTD_TOKEN_DTOGGLE;
1537 0122f472 Gerd Hoffmann
    q->qh.token &= ~QTD_TOKEN_ACTIVE;
1538 94527ead Gerd Hoffmann
1539 553a6a59 Hans de Goede
    if (q->qh.token & QTD_TOKEN_IOC) {
1540 7efc17af Gerd Hoffmann
        ehci_raise_irq(q->ehci, USBSTS_INT);
1541 44272b0f Hans de Goede
        if (q->async) {
1542 44272b0f Hans de Goede
            q->ehci->int_req_by_async = true;
1543 44272b0f Hans de Goede
        }
1544 94527ead Gerd Hoffmann
    }
1545 94527ead Gerd Hoffmann
}
1546 94527ead Gerd Hoffmann
1547 94527ead Gerd Hoffmann
// 4.10.3
1548 94527ead Gerd Hoffmann
1549 773dc9cd Gerd Hoffmann
static int ehci_execute(EHCIPacket *p, const char *action)
1550 94527ead Gerd Hoffmann
{
1551 079d0b7f Gerd Hoffmann
    USBEndpoint *ep;
1552 94527ead Gerd Hoffmann
    int ret;
1553 94527ead Gerd Hoffmann
    int endp;
1554 94527ead Gerd Hoffmann
1555 ef5b2344 Hans de Goede
    assert(p->async == EHCI_ASYNC_NONE ||
1556 ef5b2344 Hans de Goede
           p->async == EHCI_ASYNC_INITIALIZED);
1557 ef5b2344 Hans de Goede
1558 4224558f Gerd Hoffmann
    if (!(p->qtd.token & QTD_TOKEN_ACTIVE)) {
1559 4224558f Gerd Hoffmann
        fprintf(stderr, "Attempting to execute inactive qtd\n");
1560 94527ead Gerd Hoffmann
        return USB_RET_PROCERR;
1561 94527ead Gerd Hoffmann
    }
1562 94527ead Gerd Hoffmann
1563 549a3c3d Hans de Goede
    if (get_field(p->qtd.token, QTD_TOKEN_TBYTES) > BUFF_SIZE) {
1564 3a8ca08e Hans de Goede
        ehci_trace_guest_bug(p->queue->ehci,
1565 3a8ca08e Hans de Goede
                             "guest requested more bytes than allowed");
1566 94527ead Gerd Hoffmann
        return USB_RET_PROCERR;
1567 94527ead Gerd Hoffmann
    }
1568 94527ead Gerd Hoffmann
1569 4224558f Gerd Hoffmann
    p->pid = (p->qtd.token & QTD_TOKEN_PID_MASK) >> QTD_TOKEN_PID_SH;
1570 eb36a88e Gerd Hoffmann
    switch (p->pid) {
1571 eb36a88e Gerd Hoffmann
    case 0:
1572 eb36a88e Gerd Hoffmann
        p->pid = USB_TOKEN_OUT;
1573 eb36a88e Gerd Hoffmann
        break;
1574 eb36a88e Gerd Hoffmann
    case 1:
1575 eb36a88e Gerd Hoffmann
        p->pid = USB_TOKEN_IN;
1576 eb36a88e Gerd Hoffmann
        break;
1577 eb36a88e Gerd Hoffmann
    case 2:
1578 eb36a88e Gerd Hoffmann
        p->pid = USB_TOKEN_SETUP;
1579 eb36a88e Gerd Hoffmann
        break;
1580 eb36a88e Gerd Hoffmann
    default:
1581 eb36a88e Gerd Hoffmann
        fprintf(stderr, "bad token\n");
1582 eb36a88e Gerd Hoffmann
        break;
1583 94527ead Gerd Hoffmann
    }
1584 94527ead Gerd Hoffmann
1585 4224558f Gerd Hoffmann
    endp = get_field(p->queue->qh.epchar, QH_EPCHAR_EP);
1586 e59928b3 Gerd Hoffmann
    ep = usb_ep_get(p->queue->dev, p->pid, endp);
1587 94527ead Gerd Hoffmann
1588 ef5b2344 Hans de Goede
    if (p->async == EHCI_ASYNC_NONE) {
1589 ef5b2344 Hans de Goede
        if (ehci_init_transfer(p) != 0) {
1590 ef5b2344 Hans de Goede
            return USB_RET_PROCERR;
1591 ef5b2344 Hans de Goede
        }
1592 ef5b2344 Hans de Goede
1593 ef5b2344 Hans de Goede
        usb_packet_setup(&p->packet, p->pid, ep, p->qtdaddr);
1594 ef5b2344 Hans de Goede
        usb_packet_map(&p->packet, &p->sgl);
1595 ef5b2344 Hans de Goede
        p->async = EHCI_ASYNC_INITIALIZED;
1596 ef5b2344 Hans de Goede
    }
1597 0ce668bc Gerd Hoffmann
1598 773dc9cd Gerd Hoffmann
    trace_usb_ehci_packet_action(p->queue, p, action);
1599 e59928b3 Gerd Hoffmann
    ret = usb_handle_packet(p->queue->dev, &p->packet);
1600 549a3c3d Hans de Goede
    DPRINTF("submit: qh %x next %x qtd %x pid %x len %zd endp %x ret %d\n",
1601 828143c6 Gerd Hoffmann
            q->qhaddr, q->qh.next, q->qtdaddr, q->pid,
1602 549a3c3d Hans de Goede
            q->packet.iov.size, endp, ret);
1603 94527ead Gerd Hoffmann
1604 94527ead Gerd Hoffmann
    if (ret > BUFF_SIZE) {
1605 94527ead Gerd Hoffmann
        fprintf(stderr, "ret from usb_handle_packet > BUFF_SIZE\n");
1606 94527ead Gerd Hoffmann
        return USB_RET_PROCERR;
1607 94527ead Gerd Hoffmann
    }
1608 94527ead Gerd Hoffmann
1609 94527ead Gerd Hoffmann
    return ret;
1610 94527ead Gerd Hoffmann
}
1611 94527ead Gerd Hoffmann
1612 94527ead Gerd Hoffmann
/*  4.7.2
1613 94527ead Gerd Hoffmann
 */
1614 94527ead Gerd Hoffmann
1615 94527ead Gerd Hoffmann
static int ehci_process_itd(EHCIState *ehci,
1616 e983395d Gerd Hoffmann
                            EHCIitd *itd,
1617 e983395d Gerd Hoffmann
                            uint32_t addr)
1618 94527ead Gerd Hoffmann
{
1619 94527ead Gerd Hoffmann
    USBDevice *dev;
1620 079d0b7f Gerd Hoffmann
    USBEndpoint *ep;
1621 94527ead Gerd Hoffmann
    int ret;
1622 828143c6 Gerd Hoffmann
    uint32_t i, len, pid, dir, devaddr, endp;
1623 e654887f Gerd Hoffmann
    uint32_t pg, off, ptr1, ptr2, max, mult;
1624 94527ead Gerd Hoffmann
1625 94527ead Gerd Hoffmann
    dir =(itd->bufptr[1] & ITD_BUFPTR_DIRECTION);
1626 e654887f Gerd Hoffmann
    devaddr = get_field(itd->bufptr[0], ITD_BUFPTR_DEVADDR);
1627 94527ead Gerd Hoffmann
    endp = get_field(itd->bufptr[0], ITD_BUFPTR_EP);
1628 e654887f Gerd Hoffmann
    max = get_field(itd->bufptr[1], ITD_BUFPTR_MAXPKT);
1629 e654887f Gerd Hoffmann
    mult = get_field(itd->bufptr[2], ITD_BUFPTR_MULT);
1630 94527ead Gerd Hoffmann
1631 94527ead Gerd Hoffmann
    for(i = 0; i < 8; i++) {
1632 94527ead Gerd Hoffmann
        if (itd->transact[i] & ITD_XACT_ACTIVE) {
1633 e654887f Gerd Hoffmann
            pg   = get_field(itd->transact[i], ITD_XACT_PGSEL);
1634 e654887f Gerd Hoffmann
            off  = itd->transact[i] & ITD_XACT_OFFSET_MASK;
1635 e654887f Gerd Hoffmann
            ptr1 = (itd->bufptr[pg] & ITD_BUFPTR_MASK);
1636 e654887f Gerd Hoffmann
            ptr2 = (itd->bufptr[pg+1] & ITD_BUFPTR_MASK);
1637 e654887f Gerd Hoffmann
            len  = get_field(itd->transact[i], ITD_XACT_LENGTH);
1638 e654887f Gerd Hoffmann
1639 e654887f Gerd Hoffmann
            if (len > max * mult) {
1640 e654887f Gerd Hoffmann
                len = max * mult;
1641 e654887f Gerd Hoffmann
            }
1642 94527ead Gerd Hoffmann
1643 94527ead Gerd Hoffmann
            if (len > BUFF_SIZE) {
1644 94527ead Gerd Hoffmann
                return USB_RET_PROCERR;
1645 94527ead Gerd Hoffmann
            }
1646 94527ead Gerd Hoffmann
1647 68d55358 David Gibson
            pci_dma_sglist_init(&ehci->isgl, &ehci->dev, 2);
1648 e654887f Gerd Hoffmann
            if (off + len > 4096) {
1649 e654887f Gerd Hoffmann
                /* transfer crosses page border */
1650 0ce668bc Gerd Hoffmann
                uint32_t len2 = off + len - 4096;
1651 0ce668bc Gerd Hoffmann
                uint32_t len1 = len - len2;
1652 0ce668bc Gerd Hoffmann
                qemu_sglist_add(&ehci->isgl, ptr1 + off, len1);
1653 0ce668bc Gerd Hoffmann
                qemu_sglist_add(&ehci->isgl, ptr2, len2);
1654 e654887f Gerd Hoffmann
            } else {
1655 0ce668bc Gerd Hoffmann
                qemu_sglist_add(&ehci->isgl, ptr1 + off, len);
1656 e654887f Gerd Hoffmann
            }
1657 94527ead Gerd Hoffmann
1658 0ce668bc Gerd Hoffmann
            pid = dir ? USB_TOKEN_IN : USB_TOKEN_OUT;
1659 94527ead Gerd Hoffmann
1660 079d0b7f Gerd Hoffmann
            dev = ehci_find_device(ehci, devaddr);
1661 079d0b7f Gerd Hoffmann
            ep = usb_ep_get(dev, pid, endp);
1662 7ce86aa1 Hans de Goede
            if (ep && ep->type == USB_ENDPOINT_XFER_ISOC) {
1663 e983395d Gerd Hoffmann
                usb_packet_setup(&ehci->ipacket, pid, ep, addr);
1664 aa0568ff Gerd Hoffmann
                usb_packet_map(&ehci->ipacket, &ehci->isgl);
1665 aa0568ff Gerd Hoffmann
                ret = usb_handle_packet(dev, &ehci->ipacket);
1666 aa0568ff Gerd Hoffmann
                assert(ret != USB_RET_ASYNC);
1667 e2f89926 David Gibson
                usb_packet_unmap(&ehci->ipacket, &ehci->isgl);
1668 aa0568ff Gerd Hoffmann
            } else {
1669 aa0568ff Gerd Hoffmann
                DPRINTF("ISOCH: attempt to addess non-iso endpoint\n");
1670 aa0568ff Gerd Hoffmann
                ret = USB_RET_NAK;
1671 aa0568ff Gerd Hoffmann
            }
1672 0ce668bc Gerd Hoffmann
            qemu_sglist_destroy(&ehci->isgl);
1673 0ce668bc Gerd Hoffmann
1674 5eafd438 Hans de Goede
            if (ret < 0) {
1675 df787185 Hans de Goede
                switch (ret) {
1676 df787185 Hans de Goede
                default:
1677 df787185 Hans de Goede
                    fprintf(stderr, "Unexpected iso usb result: %d\n", ret);
1678 df787185 Hans de Goede
                    /* Fall through */
1679 d61000a8 Hans de Goede
                case USB_RET_IOERROR:
1680 df787185 Hans de Goede
                case USB_RET_NODEV:
1681 df787185 Hans de Goede
                    /* 3.3.2: XACTERR is only allowed on IN transactions */
1682 df787185 Hans de Goede
                    if (dir) {
1683 df787185 Hans de Goede
                        itd->transact[i] |= ITD_XACT_XACTERR;
1684 7efc17af Gerd Hoffmann
                        ehci_raise_irq(ehci, USBSTS_ERRINT);
1685 df787185 Hans de Goede
                    }
1686 df787185 Hans de Goede
                    break;
1687 df787185 Hans de Goede
                case USB_RET_BABBLE:
1688 df787185 Hans de Goede
                    itd->transact[i] |= ITD_XACT_BABBLE;
1689 7efc17af Gerd Hoffmann
                    ehci_raise_irq(ehci, USBSTS_ERRINT);
1690 df787185 Hans de Goede
                    break;
1691 5eafd438 Hans de Goede
                case USB_RET_NAK:
1692 5eafd438 Hans de Goede
                    /* no data for us, so do a zero-length transfer */
1693 5eafd438 Hans de Goede
                    ret = 0;
1694 5eafd438 Hans de Goede
                    break;
1695 5eafd438 Hans de Goede
                }
1696 5eafd438 Hans de Goede
            }
1697 5eafd438 Hans de Goede
            if (ret >= 0) {
1698 5eafd438 Hans de Goede
                if (!dir) {
1699 5eafd438 Hans de Goede
                    /* OUT */
1700 5eafd438 Hans de Goede
                    set_field(&itd->transact[i], len - ret, ITD_XACT_LENGTH);
1701 5eafd438 Hans de Goede
                } else {
1702 5eafd438 Hans de Goede
                    /* IN */
1703 5eafd438 Hans de Goede
                    set_field(&itd->transact[i], ret, ITD_XACT_LENGTH);
1704 94527ead Gerd Hoffmann
                }
1705 94527ead Gerd Hoffmann
            }
1706 df787185 Hans de Goede
            if (itd->transact[i] & ITD_XACT_IOC) {
1707 7efc17af Gerd Hoffmann
                ehci_raise_irq(ehci, USBSTS_INT);
1708 df787185 Hans de Goede
            }
1709 e654887f Gerd Hoffmann
            itd->transact[i] &= ~ITD_XACT_ACTIVE;
1710 94527ead Gerd Hoffmann
        }
1711 94527ead Gerd Hoffmann
    }
1712 94527ead Gerd Hoffmann
    return 0;
1713 94527ead Gerd Hoffmann
}
1714 94527ead Gerd Hoffmann
1715 cd665715 Gerd Hoffmann
1716 94527ead Gerd Hoffmann
/*  This state is the entry point for asynchronous schedule
1717 94527ead Gerd Hoffmann
 *  processing.  Entry here consitutes a EHCI start event state (4.8.5)
1718 94527ead Gerd Hoffmann
 */
1719 26d53979 Gerd Hoffmann
static int ehci_state_waitlisthead(EHCIState *ehci,  int async)
1720 94527ead Gerd Hoffmann
{
1721 0122f472 Gerd Hoffmann
    EHCIqh qh;
1722 94527ead Gerd Hoffmann
    int i = 0;
1723 94527ead Gerd Hoffmann
    int again = 0;
1724 94527ead Gerd Hoffmann
    uint32_t entry = ehci->asynclistaddr;
1725 94527ead Gerd Hoffmann
1726 94527ead Gerd Hoffmann
    /* set reclamation flag at start event (4.8.6) */
1727 94527ead Gerd Hoffmann
    if (async) {
1728 439a97cc Gerd Hoffmann
        ehci_set_usbsts(ehci, USBSTS_REC);
1729 94527ead Gerd Hoffmann
    }
1730 94527ead Gerd Hoffmann
1731 8f5457eb Hans de Goede
    ehci_queues_rip_unused(ehci, async);
1732 8ac6d699 Gerd Hoffmann
1733 94527ead Gerd Hoffmann
    /*  Find the head of the list (4.9.1.1) */
1734 94527ead Gerd Hoffmann
    for(i = 0; i < MAX_QH; i++) {
1735 68d55358 David Gibson
        get_dwords(ehci, NLPTR_GET(entry), (uint32_t *) &qh,
1736 68d55358 David Gibson
                   sizeof(EHCIqh) >> 2);
1737 8ac6d699 Gerd Hoffmann
        ehci_trace_qh(NULL, NLPTR_GET(entry), &qh);
1738 94527ead Gerd Hoffmann
1739 0122f472 Gerd Hoffmann
        if (qh.epchar & QH_EPCHAR_H) {
1740 94527ead Gerd Hoffmann
            if (async) {
1741 94527ead Gerd Hoffmann
                entry |= (NLPTR_TYPE_QH << 1);
1742 94527ead Gerd Hoffmann
            }
1743 94527ead Gerd Hoffmann
1744 0122f472 Gerd Hoffmann
            ehci_set_fetch_addr(ehci, async, entry);
1745 26d53979 Gerd Hoffmann
            ehci_set_state(ehci, async, EST_FETCHENTRY);
1746 94527ead Gerd Hoffmann
            again = 1;
1747 94527ead Gerd Hoffmann
            goto out;
1748 94527ead Gerd Hoffmann
        }
1749 94527ead Gerd Hoffmann
1750 0122f472 Gerd Hoffmann
        entry = qh.next;
1751 94527ead Gerd Hoffmann
        if (entry == ehci->asynclistaddr) {
1752 94527ead Gerd Hoffmann
            break;
1753 94527ead Gerd Hoffmann
        }
1754 94527ead Gerd Hoffmann
    }
1755 94527ead Gerd Hoffmann
1756 94527ead Gerd Hoffmann
    /* no head found for list. */
1757 94527ead Gerd Hoffmann
1758 26d53979 Gerd Hoffmann
    ehci_set_state(ehci, async, EST_ACTIVE);
1759 94527ead Gerd Hoffmann
1760 94527ead Gerd Hoffmann
out:
1761 94527ead Gerd Hoffmann
    return again;
1762 94527ead Gerd Hoffmann
}
1763 94527ead Gerd Hoffmann
1764 94527ead Gerd Hoffmann
1765 94527ead Gerd Hoffmann
/*  This state is the entry point for periodic schedule processing as
1766 94527ead Gerd Hoffmann
 *  well as being a continuation state for async processing.
1767 94527ead Gerd Hoffmann
 */
1768 26d53979 Gerd Hoffmann
static int ehci_state_fetchentry(EHCIState *ehci, int async)
1769 94527ead Gerd Hoffmann
{
1770 94527ead Gerd Hoffmann
    int again = 0;
1771 0122f472 Gerd Hoffmann
    uint32_t entry = ehci_get_fetch_addr(ehci, async);
1772 94527ead Gerd Hoffmann
1773 2a5ff735 Hans de Goede
    if (NLPTR_TBIT(entry)) {
1774 26d53979 Gerd Hoffmann
        ehci_set_state(ehci, async, EST_ACTIVE);
1775 94527ead Gerd Hoffmann
        goto out;
1776 94527ead Gerd Hoffmann
    }
1777 94527ead Gerd Hoffmann
1778 94527ead Gerd Hoffmann
    /* section 4.8, only QH in async schedule */
1779 94527ead Gerd Hoffmann
    if (async && (NLPTR_TYPE_GET(entry) != NLPTR_TYPE_QH)) {
1780 94527ead Gerd Hoffmann
        fprintf(stderr, "non queue head request in async schedule\n");
1781 94527ead Gerd Hoffmann
        return -1;
1782 94527ead Gerd Hoffmann
    }
1783 94527ead Gerd Hoffmann
1784 94527ead Gerd Hoffmann
    switch (NLPTR_TYPE_GET(entry)) {
1785 94527ead Gerd Hoffmann
    case NLPTR_TYPE_QH:
1786 26d53979 Gerd Hoffmann
        ehci_set_state(ehci, async, EST_FETCHQH);
1787 94527ead Gerd Hoffmann
        again = 1;
1788 94527ead Gerd Hoffmann
        break;
1789 94527ead Gerd Hoffmann
1790 94527ead Gerd Hoffmann
    case NLPTR_TYPE_ITD:
1791 26d53979 Gerd Hoffmann
        ehci_set_state(ehci, async, EST_FETCHITD);
1792 94527ead Gerd Hoffmann
        again = 1;
1793 94527ead Gerd Hoffmann
        break;
1794 94527ead Gerd Hoffmann
1795 2fe80192 Gerd Hoffmann
    case NLPTR_TYPE_STITD:
1796 2fe80192 Gerd Hoffmann
        ehci_set_state(ehci, async, EST_FETCHSITD);
1797 2fe80192 Gerd Hoffmann
        again = 1;
1798 2fe80192 Gerd Hoffmann
        break;
1799 2fe80192 Gerd Hoffmann
1800 94527ead Gerd Hoffmann
    default:
1801 2fe80192 Gerd Hoffmann
        /* TODO: handle FSTN type */
1802 94527ead Gerd Hoffmann
        fprintf(stderr, "FETCHENTRY: entry at %X is of type %d "
1803 94527ead Gerd Hoffmann
                "which is not supported yet\n", entry, NLPTR_TYPE_GET(entry));
1804 94527ead Gerd Hoffmann
        return -1;
1805 94527ead Gerd Hoffmann
    }
1806 94527ead Gerd Hoffmann
1807 94527ead Gerd Hoffmann
out:
1808 94527ead Gerd Hoffmann
    return again;
1809 94527ead Gerd Hoffmann
}
1810 94527ead Gerd Hoffmann
1811 0122f472 Gerd Hoffmann
static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async)
1812 94527ead Gerd Hoffmann
{
1813 eb36a88e Gerd Hoffmann
    EHCIPacket *p;
1814 dafe31fc Hans de Goede
    uint32_t entry, devaddr, endp;
1815 0122f472 Gerd Hoffmann
    EHCIQueue *q;
1816 dafe31fc Hans de Goede
    EHCIqh qh;
1817 94527ead Gerd Hoffmann
1818 0122f472 Gerd Hoffmann
    entry = ehci_get_fetch_addr(ehci, async);
1819 df5d5c5c Hans de Goede
    q = ehci_find_queue_by_qh(ehci, entry, async);
1820 8ac6d699 Gerd Hoffmann
    if (NULL == q) {
1821 8f6d5e26 Gerd Hoffmann
        q = ehci_alloc_queue(ehci, entry, async);
1822 8ac6d699 Gerd Hoffmann
    }
1823 eb36a88e Gerd Hoffmann
    p = QTAILQ_FIRST(&q->packets);
1824 8ac6d699 Gerd Hoffmann
1825 8f6d5e26 Gerd Hoffmann
    q->seen++;
1826 8ac6d699 Gerd Hoffmann
    if (q->seen > 1) {
1827 8ac6d699 Gerd Hoffmann
        /* we are going in circles -- stop processing */
1828 8ac6d699 Gerd Hoffmann
        ehci_set_state(ehci, async, EST_ACTIVE);
1829 8ac6d699 Gerd Hoffmann
        q = NULL;
1830 8ac6d699 Gerd Hoffmann
        goto out;
1831 8ac6d699 Gerd Hoffmann
    }
1832 94527ead Gerd Hoffmann
1833 68d55358 David Gibson
    get_dwords(ehci, NLPTR_GET(q->qhaddr),
1834 dafe31fc Hans de Goede
               (uint32_t *) &qh, sizeof(EHCIqh) >> 2);
1835 dafe31fc Hans de Goede
    ehci_trace_qh(q, NLPTR_GET(q->qhaddr), &qh);
1836 dafe31fc Hans de Goede
1837 dafe31fc Hans de Goede
    /*
1838 dafe31fc Hans de Goede
     * The overlay area of the qh should never be changed by the guest,
1839 dafe31fc Hans de Goede
     * except when idle, in which case the reset is a nop.
1840 dafe31fc Hans de Goede
     */
1841 dafe31fc Hans de Goede
    devaddr = get_field(qh.epchar, QH_EPCHAR_DEVADDR);
1842 dafe31fc Hans de Goede
    endp    = get_field(qh.epchar, QH_EPCHAR_EP);
1843 dafe31fc Hans de Goede
    if ((devaddr != get_field(q->qh.epchar, QH_EPCHAR_DEVADDR)) ||
1844 dafe31fc Hans de Goede
        (endp    != get_field(q->qh.epchar, QH_EPCHAR_EP)) ||
1845 dafe31fc Hans de Goede
        (memcmp(&qh.current_qtd, &q->qh.current_qtd,
1846 dafe31fc Hans de Goede
                                 9 * sizeof(uint32_t)) != 0) ||
1847 dafe31fc Hans de Goede
        (q->dev != NULL && q->dev->addr != devaddr)) {
1848 5c514681 Gerd Hoffmann
        if (ehci_reset_queue(q) > 0) {
1849 5c514681 Gerd Hoffmann
            ehci_trace_guest_bug(ehci, "guest updated active QH");
1850 5c514681 Gerd Hoffmann
        }
1851 dafe31fc Hans de Goede
        p = NULL;
1852 dafe31fc Hans de Goede
    }
1853 dafe31fc Hans de Goede
    q->qh = qh;
1854 dafe31fc Hans de Goede
1855 cae5d3f4 Hans de Goede
    q->transact_ctr = get_field(q->qh.epcap, QH_EPCAP_MULT);
1856 cae5d3f4 Hans de Goede
    if (q->transact_ctr == 0) { /* Guest bug in some versions of windows */
1857 cae5d3f4 Hans de Goede
        q->transact_ctr = 4;
1858 cae5d3f4 Hans de Goede
    }
1859 cae5d3f4 Hans de Goede
1860 e59928b3 Gerd Hoffmann
    if (q->dev == NULL) {
1861 e59928b3 Gerd Hoffmann
        q->dev = ehci_find_device(q->ehci, devaddr);
1862 e59928b3 Gerd Hoffmann
    }
1863 e59928b3 Gerd Hoffmann
1864 eb36a88e Gerd Hoffmann
    if (p && p->async == EHCI_ASYNC_FINISHED) {
1865 8ac6d699 Gerd Hoffmann
        /* I/O finished -- continue processing queue */
1866 773dc9cd Gerd Hoffmann
        trace_usb_ehci_packet_action(p->queue, p, "complete");
1867 8ac6d699 Gerd Hoffmann
        ehci_set_state(ehci, async, EST_EXECUTING);
1868 8ac6d699 Gerd Hoffmann
        goto out;
1869 8ac6d699 Gerd Hoffmann
    }
1870 0122f472 Gerd Hoffmann
1871 0122f472 Gerd Hoffmann
    if (async && (q->qh.epchar & QH_EPCHAR_H)) {
1872 94527ead Gerd Hoffmann
1873 94527ead Gerd Hoffmann
        /*  EHCI spec version 1.0 Section 4.8.3 & 4.10.1 */
1874 94527ead Gerd Hoffmann
        if (ehci->usbsts & USBSTS_REC) {
1875 439a97cc Gerd Hoffmann
            ehci_clear_usbsts(ehci, USBSTS_REC);
1876 94527ead Gerd Hoffmann
        } else {
1877 94527ead Gerd Hoffmann
            DPRINTF("FETCHQH:  QH 0x%08x. H-bit set, reclamation status reset"
1878 0122f472 Gerd Hoffmann
                       " - done processing\n", q->qhaddr);
1879 26d53979 Gerd Hoffmann
            ehci_set_state(ehci, async, EST_ACTIVE);
1880 0122f472 Gerd Hoffmann
            q = NULL;
1881 94527ead Gerd Hoffmann
            goto out;
1882 94527ead Gerd Hoffmann
        }
1883 94527ead Gerd Hoffmann
    }
1884 94527ead Gerd Hoffmann
1885 94527ead Gerd Hoffmann
#if EHCI_DEBUG
1886 0122f472 Gerd Hoffmann
    if (q->qhaddr != q->qh.next) {
1887 94527ead Gerd Hoffmann
    DPRINTF("FETCHQH:  QH 0x%08x (h %x halt %x active %x) next 0x%08x\n",
1888 0122f472 Gerd Hoffmann
               q->qhaddr,
1889 0122f472 Gerd Hoffmann
               q->qh.epchar & QH_EPCHAR_H,
1890 0122f472 Gerd Hoffmann
               q->qh.token & QTD_TOKEN_HALT,
1891 0122f472 Gerd Hoffmann
               q->qh.token & QTD_TOKEN_ACTIVE,
1892 0122f472 Gerd Hoffmann
               q->qh.next);
1893 94527ead Gerd Hoffmann
    }
1894 94527ead Gerd Hoffmann
#endif
1895 94527ead Gerd Hoffmann
1896 0122f472 Gerd Hoffmann
    if (q->qh.token & QTD_TOKEN_HALT) {
1897 26d53979 Gerd Hoffmann
        ehci_set_state(ehci, async, EST_HORIZONTALQH);
1898 94527ead Gerd Hoffmann
1899 2a5ff735 Hans de Goede
    } else if ((q->qh.token & QTD_TOKEN_ACTIVE) &&
1900 2a5ff735 Hans de Goede
               (NLPTR_TBIT(q->qh.current_qtd) == 0)) {
1901 0122f472 Gerd Hoffmann
        q->qtdaddr = q->qh.current_qtd;
1902 26d53979 Gerd Hoffmann
        ehci_set_state(ehci, async, EST_FETCHQTD);
1903 94527ead Gerd Hoffmann
1904 94527ead Gerd Hoffmann
    } else {
1905 94527ead Gerd Hoffmann
        /*  EHCI spec version 1.0 Section 4.10.2 */
1906 26d53979 Gerd Hoffmann
        ehci_set_state(ehci, async, EST_ADVANCEQUEUE);
1907 94527ead Gerd Hoffmann
    }
1908 94527ead Gerd Hoffmann
1909 94527ead Gerd Hoffmann
out:
1910 0122f472 Gerd Hoffmann
    return q;
1911 94527ead Gerd Hoffmann
}
1912 94527ead Gerd Hoffmann
1913 26d53979 Gerd Hoffmann
static int ehci_state_fetchitd(EHCIState *ehci, int async)
1914 94527ead Gerd Hoffmann
{
1915 0122f472 Gerd Hoffmann
    uint32_t entry;
1916 94527ead Gerd Hoffmann
    EHCIitd itd;
1917 94527ead Gerd Hoffmann
1918 0122f472 Gerd Hoffmann
    assert(!async);
1919 0122f472 Gerd Hoffmann
    entry = ehci_get_fetch_addr(ehci, async);
1920 0122f472 Gerd Hoffmann
1921 68d55358 David Gibson
    get_dwords(ehci, NLPTR_GET(entry), (uint32_t *) &itd,
1922 94527ead Gerd Hoffmann
               sizeof(EHCIitd) >> 2);
1923 0122f472 Gerd Hoffmann
    ehci_trace_itd(ehci, entry, &itd);
1924 94527ead Gerd Hoffmann
1925 e983395d Gerd Hoffmann
    if (ehci_process_itd(ehci, &itd, entry) != 0) {
1926 94527ead Gerd Hoffmann
        return -1;
1927 94527ead Gerd Hoffmann
    }
1928 94527ead Gerd Hoffmann
1929 68d55358 David Gibson
    put_dwords(ehci, NLPTR_GET(entry), (uint32_t *) &itd,
1930 68d55358 David Gibson
               sizeof(EHCIitd) >> 2);
1931 0122f472 Gerd Hoffmann
    ehci_set_fetch_addr(ehci, async, itd.next);
1932 26d53979 Gerd Hoffmann
    ehci_set_state(ehci, async, EST_FETCHENTRY);
1933 94527ead Gerd Hoffmann
1934 94527ead Gerd Hoffmann
    return 1;
1935 94527ead Gerd Hoffmann
}
1936 94527ead Gerd Hoffmann
1937 2fe80192 Gerd Hoffmann
static int ehci_state_fetchsitd(EHCIState *ehci, int async)
1938 2fe80192 Gerd Hoffmann
{
1939 2fe80192 Gerd Hoffmann
    uint32_t entry;
1940 2fe80192 Gerd Hoffmann
    EHCIsitd sitd;
1941 2fe80192 Gerd Hoffmann
1942 2fe80192 Gerd Hoffmann
    assert(!async);
1943 2fe80192 Gerd Hoffmann
    entry = ehci_get_fetch_addr(ehci, async);
1944 2fe80192 Gerd Hoffmann
1945 68d55358 David Gibson
    get_dwords(ehci, NLPTR_GET(entry), (uint32_t *)&sitd,
1946 2fe80192 Gerd Hoffmann
               sizeof(EHCIsitd) >> 2);
1947 2fe80192 Gerd Hoffmann
    ehci_trace_sitd(ehci, entry, &sitd);
1948 2fe80192 Gerd Hoffmann
1949 2fe80192 Gerd Hoffmann
    if (!(sitd.results & SITD_RESULTS_ACTIVE)) {
1950 2fe80192 Gerd Hoffmann
        /* siTD is not active, nothing to do */;
1951 2fe80192 Gerd Hoffmann
    } else {
1952 2fe80192 Gerd Hoffmann
        /* TODO: split transfers are not implemented */
1953 2fe80192 Gerd Hoffmann
        fprintf(stderr, "WARNING: Skipping active siTD\n");
1954 2fe80192 Gerd Hoffmann
    }
1955 2fe80192 Gerd Hoffmann
1956 2fe80192 Gerd Hoffmann
    ehci_set_fetch_addr(ehci, async, sitd.next);
1957 2fe80192 Gerd Hoffmann
    ehci_set_state(ehci, async, EST_FETCHENTRY);
1958 2fe80192 Gerd Hoffmann
    return 1;
1959 2fe80192 Gerd Hoffmann
}
1960 2fe80192 Gerd Hoffmann
1961 94527ead Gerd Hoffmann
/* Section 4.10.2 - paragraph 3 */
1962 ae0138a8 Gerd Hoffmann
static int ehci_state_advqueue(EHCIQueue *q)
1963 94527ead Gerd Hoffmann
{
1964 94527ead Gerd Hoffmann
#if 0
1965 94527ead Gerd Hoffmann
    /* TO-DO: 4.10.2 - paragraph 2
1966 94527ead Gerd Hoffmann
     * if I-bit is set to 1 and QH is not active
1967 94527ead Gerd Hoffmann
     * go to horizontal QH
1968 94527ead Gerd Hoffmann
     */
1969 94527ead Gerd Hoffmann
    if (I-bit set) {
1970 26d53979 Gerd Hoffmann
        ehci_set_state(ehci, async, EST_HORIZONTALQH);
1971 94527ead Gerd Hoffmann
        goto out;
1972 94527ead Gerd Hoffmann
    }
1973 94527ead Gerd Hoffmann
#endif
1974 94527ead Gerd Hoffmann
1975 94527ead Gerd Hoffmann
    /*
1976 94527ead Gerd Hoffmann
     * want data and alt-next qTD is valid
1977 94527ead Gerd Hoffmann
     */
1978 0122f472 Gerd Hoffmann
    if (((q->qh.token & QTD_TOKEN_TBYTES_MASK) != 0) &&
1979 0122f472 Gerd Hoffmann
        (NLPTR_TBIT(q->qh.altnext_qtd) == 0)) {
1980 0122f472 Gerd Hoffmann
        q->qtdaddr = q->qh.altnext_qtd;
1981 ae0138a8 Gerd Hoffmann
        ehci_set_state(q->ehci, q->async, EST_FETCHQTD);
1982 94527ead Gerd Hoffmann
1983 94527ead Gerd Hoffmann
    /*
1984 94527ead Gerd Hoffmann
     *  next qTD is valid
1985 94527ead Gerd Hoffmann
     */
1986 2a5ff735 Hans de Goede
    } else if (NLPTR_TBIT(q->qh.next_qtd) == 0) {
1987 0122f472 Gerd Hoffmann
        q->qtdaddr = q->qh.next_qtd;
1988 ae0138a8 Gerd Hoffmann
        ehci_set_state(q->ehci, q->async, EST_FETCHQTD);
1989 94527ead Gerd Hoffmann
1990 94527ead Gerd Hoffmann
    /*
1991 94527ead Gerd Hoffmann
     *  no valid qTD, try next QH
1992 94527ead Gerd Hoffmann
     */
1993 94527ead Gerd Hoffmann
    } else {
1994 ae0138a8 Gerd Hoffmann
        ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
1995 94527ead Gerd Hoffmann
    }
1996 94527ead Gerd Hoffmann
1997 94527ead Gerd Hoffmann
    return 1;
1998 94527ead Gerd Hoffmann
}
1999 94527ead Gerd Hoffmann
2000 94527ead Gerd Hoffmann
/* Section 4.10.2 - paragraph 4 */
2001 ae0138a8 Gerd Hoffmann
static int ehci_state_fetchqtd(EHCIQueue *q)
2002 94527ead Gerd Hoffmann
{
2003 eb36a88e Gerd Hoffmann
    EHCIqtd qtd;
2004 eb36a88e Gerd Hoffmann
    EHCIPacket *p;
2005 b4ea8664 Hans de Goede
    int again = 1;
2006 94527ead Gerd Hoffmann
2007 eb36a88e Gerd Hoffmann
    get_dwords(q->ehci, NLPTR_GET(q->qtdaddr), (uint32_t *) &qtd,
2008 68d55358 David Gibson
               sizeof(EHCIqtd) >> 2);
2009 eb36a88e Gerd Hoffmann
    ehci_trace_qtd(q, NLPTR_GET(q->qtdaddr), &qtd);
2010 94527ead Gerd Hoffmann
2011 773dc9cd Gerd Hoffmann
    p = QTAILQ_FIRST(&q->packets);
2012 773dc9cd Gerd Hoffmann
    if (p != NULL) {
2013 287fd3f1 Gerd Hoffmann
        if (p->qtdaddr != q->qtdaddr ||
2014 287fd3f1 Gerd Hoffmann
            (!NLPTR_TBIT(p->qtd.next) && (p->qtd.next != qtd.next)) ||
2015 287fd3f1 Gerd Hoffmann
            (!NLPTR_TBIT(p->qtd.altnext) && (p->qtd.altnext != qtd.altnext)) ||
2016 287fd3f1 Gerd Hoffmann
            p->qtd.bufptr[0] != qtd.bufptr[0]) {
2017 287fd3f1 Gerd Hoffmann
            ehci_cancel_queue(q);
2018 5c514681 Gerd Hoffmann
            ehci_trace_guest_bug(q->ehci, "guest updated active QH or qTD");
2019 287fd3f1 Gerd Hoffmann
            p = NULL;
2020 287fd3f1 Gerd Hoffmann
        } else {
2021 287fd3f1 Gerd Hoffmann
            p->qtd = qtd;
2022 287fd3f1 Gerd Hoffmann
            ehci_qh_do_overlay(q);
2023 287fd3f1 Gerd Hoffmann
        }
2024 287fd3f1 Gerd Hoffmann
    }
2025 287fd3f1 Gerd Hoffmann
2026 287fd3f1 Gerd Hoffmann
    if (!(qtd.token & QTD_TOKEN_ACTIVE)) {
2027 287fd3f1 Gerd Hoffmann
        if (p != NULL) {
2028 287fd3f1 Gerd Hoffmann
            /* transfer canceled by guest (clear active) */
2029 287fd3f1 Gerd Hoffmann
            ehci_cancel_queue(q);
2030 287fd3f1 Gerd Hoffmann
            p = NULL;
2031 287fd3f1 Gerd Hoffmann
        }
2032 287fd3f1 Gerd Hoffmann
        ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
2033 287fd3f1 Gerd Hoffmann
    } else if (p != NULL) {
2034 adf47834 Hans de Goede
        switch (p->async) {
2035 adf47834 Hans de Goede
        case EHCI_ASYNC_NONE:
2036 ef5b2344 Hans de Goede
        case EHCI_ASYNC_INITIALIZED:
2037 cae5d3f4 Hans de Goede
            /* Not yet executed (MULT), or previously nacked (int) packet */
2038 ef5b2344 Hans de Goede
            ehci_set_state(q->ehci, q->async, EST_EXECUTE);
2039 ef5b2344 Hans de Goede
            break;
2040 adf47834 Hans de Goede
        case EHCI_ASYNC_INFLIGHT:
2041 b4ea8664 Hans de Goede
            /* Check if the guest has added new tds to the queue */
2042 b4ea8664 Hans de Goede
            again = (ehci_fill_queue(QTAILQ_LAST(&q->packets, pkts_head)) ==
2043 b4ea8664 Hans de Goede
                     USB_RET_PROCERR) ? -1 : 1;
2044 ef5b2344 Hans de Goede
            /* Unfinished async handled packet, go horizontal */
2045 ae0138a8 Gerd Hoffmann
            ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
2046 adf47834 Hans de Goede
            break;
2047 adf47834 Hans de Goede
        case EHCI_ASYNC_FINISHED:
2048 cf1f8169 Hans de Goede
            /*
2049 cf1f8169 Hans de Goede
             * We get here when advqueue moves to a packet which is already
2050 cf1f8169 Hans de Goede
             * finished, which can happen with packets queued up by fill_queue
2051 cf1f8169 Hans de Goede
             */
2052 ae0138a8 Gerd Hoffmann
            ehci_set_state(q->ehci, q->async, EST_EXECUTING);
2053 adf47834 Hans de Goede
            break;
2054 773dc9cd Gerd Hoffmann
        }
2055 287fd3f1 Gerd Hoffmann
    } else {
2056 eb36a88e Gerd Hoffmann
        p = ehci_alloc_packet(q);
2057 eb36a88e Gerd Hoffmann
        p->qtdaddr = q->qtdaddr;
2058 eb36a88e Gerd Hoffmann
        p->qtd = qtd;
2059 ae0138a8 Gerd Hoffmann
        ehci_set_state(q->ehci, q->async, EST_EXECUTE);
2060 94527ead Gerd Hoffmann
    }
2061 94527ead Gerd Hoffmann
2062 94527ead Gerd Hoffmann
    return again;
2063 94527ead Gerd Hoffmann
}
2064 94527ead Gerd Hoffmann
2065 ae0138a8 Gerd Hoffmann
static int ehci_state_horizqh(EHCIQueue *q)
2066 94527ead Gerd Hoffmann
{
2067 94527ead Gerd Hoffmann
    int again = 0;
2068 94527ead Gerd Hoffmann
2069 ae0138a8 Gerd Hoffmann
    if (ehci_get_fetch_addr(q->ehci, q->async) != q->qh.next) {
2070 ae0138a8 Gerd Hoffmann
        ehci_set_fetch_addr(q->ehci, q->async, q->qh.next);
2071 ae0138a8 Gerd Hoffmann
        ehci_set_state(q->ehci, q->async, EST_FETCHENTRY);
2072 94527ead Gerd Hoffmann
        again = 1;
2073 94527ead Gerd Hoffmann
    } else {
2074 ae0138a8 Gerd Hoffmann
        ehci_set_state(q->ehci, q->async, EST_ACTIVE);
2075 94527ead Gerd Hoffmann
    }
2076 94527ead Gerd Hoffmann
2077 94527ead Gerd Hoffmann
    return again;
2078 94527ead Gerd Hoffmann
}
2079 94527ead Gerd Hoffmann
2080 eff6dce7 Hans de Goede
static int ehci_fill_queue(EHCIPacket *p)
2081 773dc9cd Gerd Hoffmann
{
2082 36dfe324 Hans de Goede
    USBEndpoint *ep = p->packet.ep;
2083 773dc9cd Gerd Hoffmann
    EHCIQueue *q = p->queue;
2084 773dc9cd Gerd Hoffmann
    EHCIqtd qtd = p->qtd;
2085 e3a36bce Hans de Goede
    uint32_t qtdaddr, start_addr = p->qtdaddr;
2086 773dc9cd Gerd Hoffmann
2087 773dc9cd Gerd Hoffmann
    for (;;) {
2088 773dc9cd Gerd Hoffmann
        if (NLPTR_TBIT(qtd.altnext) == 0) {
2089 773dc9cd Gerd Hoffmann
            break;
2090 773dc9cd Gerd Hoffmann
        }
2091 773dc9cd Gerd Hoffmann
        if (NLPTR_TBIT(qtd.next) != 0) {
2092 773dc9cd Gerd Hoffmann
            break;
2093 773dc9cd Gerd Hoffmann
        }
2094 773dc9cd Gerd Hoffmann
        qtdaddr = qtd.next;
2095 e3a36bce Hans de Goede
        /*
2096 e3a36bce Hans de Goede
         * Detect circular td lists, Windows creates these, counting on the
2097 e3a36bce Hans de Goede
         * active bit going low after execution to make the queue stop.
2098 e3a36bce Hans de Goede
         */
2099 e3a36bce Hans de Goede
        if (qtdaddr == start_addr) {
2100 e3a36bce Hans de Goede
            break;
2101 e3a36bce Hans de Goede
        }
2102 773dc9cd Gerd Hoffmann
        get_dwords(q->ehci, NLPTR_GET(qtdaddr),
2103 773dc9cd Gerd Hoffmann
                   (uint32_t *) &qtd, sizeof(EHCIqtd) >> 2);
2104 773dc9cd Gerd Hoffmann
        ehci_trace_qtd(q, NLPTR_GET(qtdaddr), &qtd);
2105 773dc9cd Gerd Hoffmann
        if (!(qtd.token & QTD_TOKEN_ACTIVE)) {
2106 773dc9cd Gerd Hoffmann
            break;
2107 773dc9cd Gerd Hoffmann
        }
2108 773dc9cd Gerd Hoffmann
        p = ehci_alloc_packet(q);
2109 773dc9cd Gerd Hoffmann
        p->qtdaddr = qtdaddr;
2110 773dc9cd Gerd Hoffmann
        p->qtd = qtd;
2111 773dc9cd Gerd Hoffmann
        p->usb_status = ehci_execute(p, "queue");
2112 eff6dce7 Hans de Goede
        if (p->usb_status == USB_RET_PROCERR) {
2113 eff6dce7 Hans de Goede
            break;
2114 eff6dce7 Hans de Goede
        }
2115 df6839c7 Alejandro Martinez Ruiz
        assert(p->usb_status == USB_RET_ASYNC);
2116 773dc9cd Gerd Hoffmann
        p->async = EHCI_ASYNC_INFLIGHT;
2117 773dc9cd Gerd Hoffmann
    }
2118 36dfe324 Hans de Goede
    if (p->usb_status != USB_RET_PROCERR) {
2119 36dfe324 Hans de Goede
        usb_device_flush_ep_queue(ep->dev, ep);
2120 36dfe324 Hans de Goede
    }
2121 eff6dce7 Hans de Goede
    return p->usb_status;
2122 773dc9cd Gerd Hoffmann
}
2123 773dc9cd Gerd Hoffmann
2124 ae0138a8 Gerd Hoffmann
static int ehci_state_execute(EHCIQueue *q)
2125 94527ead Gerd Hoffmann
{
2126 eb36a88e Gerd Hoffmann
    EHCIPacket *p = QTAILQ_FIRST(&q->packets);
2127 94527ead Gerd Hoffmann
    int again = 0;
2128 94527ead Gerd Hoffmann
2129 eb36a88e Gerd Hoffmann
    assert(p != NULL);
2130 eb36a88e Gerd Hoffmann
    assert(p->qtdaddr == q->qtdaddr);
2131 eb36a88e Gerd Hoffmann
2132 0122f472 Gerd Hoffmann
    if (ehci_qh_do_overlay(q) != 0) {
2133 94527ead Gerd Hoffmann
        return -1;
2134 94527ead Gerd Hoffmann
    }
2135 94527ead Gerd Hoffmann
2136 94527ead Gerd Hoffmann
    // TODO verify enough time remains in the uframe as in 4.4.1.1
2137 94527ead Gerd Hoffmann
    // TODO write back ptr to async list when done or out of time
2138 94527ead Gerd Hoffmann
2139 cae5d3f4 Hans de Goede
    /* 4.10.3, bottom of page 82, go horizontal on transaction counter == 0 */
2140 cae5d3f4 Hans de Goede
    if (!q->async && q->transact_ctr == 0) {
2141 cae5d3f4 Hans de Goede
        ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
2142 cae5d3f4 Hans de Goede
        again = 1;
2143 cae5d3f4 Hans de Goede
        goto out;
2144 94527ead Gerd Hoffmann
    }
2145 94527ead Gerd Hoffmann
2146 ae0138a8 Gerd Hoffmann
    if (q->async) {
2147 0122f472 Gerd Hoffmann
        ehci_set_usbsts(q->ehci, USBSTS_REC);
2148 94527ead Gerd Hoffmann
    }
2149 94527ead Gerd Hoffmann
2150 773dc9cd Gerd Hoffmann
    p->usb_status = ehci_execute(p, "process");
2151 eb36a88e Gerd Hoffmann
    if (p->usb_status == USB_RET_PROCERR) {
2152 94527ead Gerd Hoffmann
        again = -1;
2153 94527ead Gerd Hoffmann
        goto out;
2154 94527ead Gerd Hoffmann
    }
2155 eb36a88e Gerd Hoffmann
    if (p->usb_status == USB_RET_ASYNC) {
2156 8ac6d699 Gerd Hoffmann
        ehci_flush_qh(q);
2157 773dc9cd Gerd Hoffmann
        trace_usb_ehci_packet_action(p->queue, p, "async");
2158 eb36a88e Gerd Hoffmann
        p->async = EHCI_ASYNC_INFLIGHT;
2159 ae0138a8 Gerd Hoffmann
        ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
2160 cae5d3f4 Hans de Goede
        if (q->async) {
2161 cae5d3f4 Hans de Goede
            again = (ehci_fill_queue(p) == USB_RET_PROCERR) ? -1 : 1;
2162 cae5d3f4 Hans de Goede
        } else {
2163 cae5d3f4 Hans de Goede
            again = 1;
2164 cae5d3f4 Hans de Goede
        }
2165 8ac6d699 Gerd Hoffmann
        goto out;
2166 94527ead Gerd Hoffmann
    }
2167 94527ead Gerd Hoffmann
2168 ae0138a8 Gerd Hoffmann
    ehci_set_state(q->ehci, q->async, EST_EXECUTING);
2169 8ac6d699 Gerd Hoffmann
    again = 1;
2170 8ac6d699 Gerd Hoffmann
2171 94527ead Gerd Hoffmann
out:
2172 94527ead Gerd Hoffmann
    return again;
2173 94527ead Gerd Hoffmann
}
2174 94527ead Gerd Hoffmann
2175 ae0138a8 Gerd Hoffmann
static int ehci_state_executing(EHCIQueue *q)
2176 94527ead Gerd Hoffmann
{
2177 eb36a88e Gerd Hoffmann
    EHCIPacket *p = QTAILQ_FIRST(&q->packets);
2178 94527ead Gerd Hoffmann
2179 eb36a88e Gerd Hoffmann
    assert(p != NULL);
2180 eb36a88e Gerd Hoffmann
    assert(p->qtdaddr == q->qtdaddr);
2181 eb36a88e Gerd Hoffmann
2182 0122f472 Gerd Hoffmann
    ehci_execute_complete(q);
2183 94527ead Gerd Hoffmann
2184 cae5d3f4 Hans de Goede
    /* 4.10.3 */
2185 cae5d3f4 Hans de Goede
    if (!q->async && q->transact_ctr > 0) {
2186 cae5d3f4 Hans de Goede
        q->transact_ctr--;
2187 94527ead Gerd Hoffmann
    }
2188 94527ead Gerd Hoffmann
2189 94527ead Gerd Hoffmann
    /* 4.10.5 */
2190 eb36a88e Gerd Hoffmann
    if (p->usb_status == USB_RET_NAK) {
2191 ae0138a8 Gerd Hoffmann
        ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
2192 94527ead Gerd Hoffmann
    } else {
2193 ae0138a8 Gerd Hoffmann
        ehci_set_state(q->ehci, q->async, EST_WRITEBACK);
2194 94527ead Gerd Hoffmann
    }
2195 94527ead Gerd Hoffmann
2196 8ac6d699 Gerd Hoffmann
    ehci_flush_qh(q);
2197 574ef171 Hans de Goede
    return 1;
2198 94527ead Gerd Hoffmann
}
2199 94527ead Gerd Hoffmann
2200 94527ead Gerd Hoffmann
2201 ae0138a8 Gerd Hoffmann
static int ehci_state_writeback(EHCIQueue *q)
2202 94527ead Gerd Hoffmann
{
2203 eb36a88e Gerd Hoffmann
    EHCIPacket *p = QTAILQ_FIRST(&q->packets);
2204 4ed1c57a Gerd Hoffmann
    uint32_t *qtd, addr;
2205 94527ead Gerd Hoffmann
    int again = 0;
2206 94527ead Gerd Hoffmann
2207 94527ead Gerd Hoffmann
    /*  Write back the QTD from the QH area */
2208 eb36a88e Gerd Hoffmann
    assert(p != NULL);
2209 eb36a88e Gerd Hoffmann
    assert(p->qtdaddr == q->qtdaddr);
2210 eb36a88e Gerd Hoffmann
2211 eb36a88e Gerd Hoffmann
    ehci_trace_qtd(q, NLPTR_GET(p->qtdaddr), (EHCIqtd *) &q->qh.next_qtd);
2212 4ed1c57a Gerd Hoffmann
    qtd = (uint32_t *) &q->qh.next_qtd;
2213 4ed1c57a Gerd Hoffmann
    addr = NLPTR_GET(p->qtdaddr);
2214 4ed1c57a Gerd Hoffmann
    put_dwords(q->ehci, addr + 2 * sizeof(uint32_t), qtd + 2, 2);
2215 eb36a88e Gerd Hoffmann
    ehci_free_packet(p);
2216 94527ead Gerd Hoffmann
2217 d2bd525f Gerd Hoffmann
    /*
2218 d2bd525f Gerd Hoffmann
     * EHCI specs say go horizontal here.
2219 d2bd525f Gerd Hoffmann
     *
2220 d2bd525f Gerd Hoffmann
     * We can also advance the queue here for performance reasons.  We
2221 d2bd525f Gerd Hoffmann
     * need to take care to only take that shortcut in case we've
2222 d2bd525f Gerd Hoffmann
     * processed the qtd just written back without errors, i.e. halt
2223 d2bd525f Gerd Hoffmann
     * bit is clear.
2224 94527ead Gerd Hoffmann
     */
2225 d2bd525f Gerd Hoffmann
    if (q->qh.token & QTD_TOKEN_HALT) {
2226 ae0138a8 Gerd Hoffmann
        ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
2227 d2bd525f Gerd Hoffmann
        again = 1;
2228 d2bd525f Gerd Hoffmann
    } else {
2229 ae0138a8 Gerd Hoffmann
        ehci_set_state(q->ehci, q->async, EST_ADVANCEQUEUE);
2230 94527ead Gerd Hoffmann
        again = 1;
2231 d2bd525f Gerd Hoffmann
    }
2232 94527ead Gerd Hoffmann
    return again;
2233 94527ead Gerd Hoffmann
}
2234 94527ead Gerd Hoffmann
2235 94527ead Gerd Hoffmann
/*
2236 94527ead Gerd Hoffmann
 * This is the state machine that is common to both async and periodic
2237 94527ead Gerd Hoffmann
 */
2238 94527ead Gerd Hoffmann
2239 ae0138a8 Gerd Hoffmann
static void ehci_advance_state(EHCIState *ehci, int async)
2240 94527ead Gerd Hoffmann
{
2241 0122f472 Gerd Hoffmann
    EHCIQueue *q = NULL;
2242 94527ead Gerd Hoffmann
    int again;
2243 94527ead Gerd Hoffmann
2244 94527ead Gerd Hoffmann
    do {
2245 26d53979 Gerd Hoffmann
        switch(ehci_get_state(ehci, async)) {
2246 94527ead Gerd Hoffmann
        case EST_WAITLISTHEAD:
2247 26d53979 Gerd Hoffmann
            again = ehci_state_waitlisthead(ehci, async);
2248 94527ead Gerd Hoffmann
            break;
2249 94527ead Gerd Hoffmann
2250 94527ead Gerd Hoffmann
        case EST_FETCHENTRY:
2251 26d53979 Gerd Hoffmann
            again = ehci_state_fetchentry(ehci, async);
2252 94527ead Gerd Hoffmann
            break;
2253 94527ead Gerd Hoffmann
2254 94527ead Gerd Hoffmann
        case EST_FETCHQH:
2255 0122f472 Gerd Hoffmann
            q = ehci_state_fetchqh(ehci, async);
2256 ae0138a8 Gerd Hoffmann
            if (q != NULL) {
2257 ae0138a8 Gerd Hoffmann
                assert(q->async == async);
2258 ae0138a8 Gerd Hoffmann
                again = 1;
2259 ae0138a8 Gerd Hoffmann
            } else {
2260 ae0138a8 Gerd Hoffmann
                again = 0;
2261 ae0138a8 Gerd Hoffmann
            }
2262 94527ead Gerd Hoffmann
            break;
2263 94527ead Gerd Hoffmann
2264 94527ead Gerd Hoffmann
        case EST_FETCHITD:
2265 26d53979 Gerd Hoffmann
            again = ehci_state_fetchitd(ehci, async);
2266 94527ead Gerd Hoffmann
            break;
2267 94527ead Gerd Hoffmann
2268 2fe80192 Gerd Hoffmann
        case EST_FETCHSITD:
2269 2fe80192 Gerd Hoffmann
            again = ehci_state_fetchsitd(ehci, async);
2270 2fe80192 Gerd Hoffmann
            break;
2271 2fe80192 Gerd Hoffmann
2272 94527ead Gerd Hoffmann
        case EST_ADVANCEQUEUE:
2273 ae0138a8 Gerd Hoffmann
            again = ehci_state_advqueue(q);
2274 94527ead Gerd Hoffmann
            break;
2275 94527ead Gerd Hoffmann
2276 94527ead Gerd Hoffmann
        case EST_FETCHQTD:
2277 ae0138a8 Gerd Hoffmann
            again = ehci_state_fetchqtd(q);
2278 94527ead Gerd Hoffmann
            break;
2279 94527ead Gerd Hoffmann
2280 94527ead Gerd Hoffmann
        case EST_HORIZONTALQH:
2281 ae0138a8 Gerd Hoffmann
            again = ehci_state_horizqh(q);
2282 94527ead Gerd Hoffmann
            break;
2283 94527ead Gerd Hoffmann
2284 94527ead Gerd Hoffmann
        case EST_EXECUTE:
2285 ae0138a8 Gerd Hoffmann
            again = ehci_state_execute(q);
2286 3a215326 Gerd Hoffmann
            if (async) {
2287 3a215326 Gerd Hoffmann
                ehci->async_stepdown = 0;
2288 3a215326 Gerd Hoffmann
            }
2289 94527ead Gerd Hoffmann
            break;
2290 94527ead Gerd Hoffmann
2291 94527ead Gerd Hoffmann
        case EST_EXECUTING:
2292 8ac6d699 Gerd Hoffmann
            assert(q != NULL);
2293 3a215326 Gerd Hoffmann
            if (async) {
2294 3a215326 Gerd Hoffmann
                ehci->async_stepdown = 0;
2295 3a215326 Gerd Hoffmann
            }
2296 ae0138a8 Gerd Hoffmann
            again = ehci_state_executing(q);
2297 94527ead Gerd Hoffmann
            break;
2298 94527ead Gerd Hoffmann
2299 94527ead Gerd Hoffmann
        case EST_WRITEBACK:
2300 b2467216 Gerd Hoffmann
            assert(q != NULL);
2301 ae0138a8 Gerd Hoffmann
            again = ehci_state_writeback(q);
2302 94527ead Gerd Hoffmann
            break;
2303 94527ead Gerd Hoffmann
2304 94527ead Gerd Hoffmann
        default:
2305 94527ead Gerd Hoffmann
            fprintf(stderr, "Bad state!\n");
2306 94527ead Gerd Hoffmann
            again = -1;
2307 8ac6d699 Gerd Hoffmann
            assert(0);
2308 94527ead Gerd Hoffmann
            break;
2309 94527ead Gerd Hoffmann
        }
2310 94527ead Gerd Hoffmann
2311 94527ead Gerd Hoffmann
        if (again < 0) {
2312 94527ead Gerd Hoffmann
            fprintf(stderr, "processing error - resetting ehci HC\n");
2313 94527ead Gerd Hoffmann
            ehci_reset(ehci);
2314 94527ead Gerd Hoffmann
            again = 0;
2315 94527ead Gerd Hoffmann
        }
2316 94527ead Gerd Hoffmann
    }
2317 94527ead Gerd Hoffmann
    while (again);
2318 94527ead Gerd Hoffmann
}
2319 94527ead Gerd Hoffmann
2320 94527ead Gerd Hoffmann
static void ehci_advance_async_state(EHCIState *ehci)
2321 94527ead Gerd Hoffmann
{
2322 df5d5c5c Hans de Goede
    const int async = 1;
2323 94527ead Gerd Hoffmann
2324 26d53979 Gerd Hoffmann
    switch(ehci_get_state(ehci, async)) {
2325 94527ead Gerd Hoffmann
    case EST_INACTIVE:
2326 ec807d12 Gerd Hoffmann
        if (!ehci_async_enabled(ehci)) {
2327 94527ead Gerd Hoffmann
            break;
2328 94527ead Gerd Hoffmann
        }
2329 26d53979 Gerd Hoffmann
        ehci_set_state(ehci, async, EST_ACTIVE);
2330 94527ead Gerd Hoffmann
        // No break, fall through to ACTIVE
2331 94527ead Gerd Hoffmann
2332 94527ead Gerd Hoffmann
    case EST_ACTIVE:
2333 ec807d12 Gerd Hoffmann
        if (!ehci_async_enabled(ehci)) {
2334 e850c2b4 Hans de Goede
            ehci_queues_rip_all(ehci, async);
2335 26d53979 Gerd Hoffmann
            ehci_set_state(ehci, async, EST_INACTIVE);
2336 94527ead Gerd Hoffmann
            break;
2337 94527ead Gerd Hoffmann
        }
2338 94527ead Gerd Hoffmann
2339 4be23939 Hans de Goede
        /* make sure guest has acknowledged the doorbell interrupt */
2340 94527ead Gerd Hoffmann
        /* TO-DO: is this really needed? */
2341 94527ead Gerd Hoffmann
        if (ehci->usbsts & USBSTS_IAA) {
2342 94527ead Gerd Hoffmann
            DPRINTF("IAA status bit still set.\n");
2343 94527ead Gerd Hoffmann
            break;
2344 94527ead Gerd Hoffmann
        }
2345 94527ead Gerd Hoffmann
2346 94527ead Gerd Hoffmann
        /* check that address register has been set */
2347 94527ead Gerd Hoffmann
        if (ehci->asynclistaddr == 0) {
2348 94527ead Gerd Hoffmann
            break;
2349 94527ead Gerd Hoffmann
        }
2350 94527ead Gerd Hoffmann
2351 26d53979 Gerd Hoffmann
        ehci_set_state(ehci, async, EST_WAITLISTHEAD);
2352 26d53979 Gerd Hoffmann
        ehci_advance_state(ehci, async);
2353 4be23939 Hans de Goede
2354 4be23939 Hans de Goede
        /* If the doorbell is set, the guest wants to make a change to the
2355 4be23939 Hans de Goede
         * schedule. The host controller needs to release cached data.
2356 4be23939 Hans de Goede
         * (section 4.8.2)
2357 4be23939 Hans de Goede
         */
2358 4be23939 Hans de Goede
        if (ehci->usbcmd & USBCMD_IAAD) {
2359 4be23939 Hans de Goede
            /* Remove all unseen qhs from the async qhs queue */
2360 8f5457eb Hans de Goede
            ehci_queues_rip_unseen(ehci, async);
2361 1defcbd1 Gerd Hoffmann
            trace_usb_ehci_doorbell_ack();
2362 4be23939 Hans de Goede
            ehci->usbcmd &= ~USBCMD_IAAD;
2363 7efc17af Gerd Hoffmann
            ehci_raise_irq(ehci, USBSTS_IAA);
2364 4be23939 Hans de Goede
        }
2365 94527ead Gerd Hoffmann
        break;
2366 94527ead Gerd Hoffmann
2367 94527ead Gerd Hoffmann
    default:
2368 94527ead Gerd Hoffmann
        /* this should only be due to a developer mistake */
2369 94527ead Gerd Hoffmann
        fprintf(stderr, "ehci: Bad asynchronous state %d. "
2370 94527ead Gerd Hoffmann
                "Resetting to active\n", ehci->astate);
2371 0122f472 Gerd Hoffmann
        assert(0);
2372 94527ead Gerd Hoffmann
    }
2373 94527ead Gerd Hoffmann
}
2374 94527ead Gerd Hoffmann
2375 94527ead Gerd Hoffmann
static void ehci_advance_periodic_state(EHCIState *ehci)
2376 94527ead Gerd Hoffmann
{
2377 94527ead Gerd Hoffmann
    uint32_t entry;
2378 94527ead Gerd Hoffmann
    uint32_t list;
2379 df5d5c5c Hans de Goede
    const int async = 0;
2380 94527ead Gerd Hoffmann
2381 94527ead Gerd Hoffmann
    // 4.6
2382 94527ead Gerd Hoffmann
2383 26d53979 Gerd Hoffmann
    switch(ehci_get_state(ehci, async)) {
2384 94527ead Gerd Hoffmann
    case EST_INACTIVE:
2385 ec807d12 Gerd Hoffmann
        if (!(ehci->frindex & 7) && ehci_periodic_enabled(ehci)) {
2386 26d53979 Gerd Hoffmann
            ehci_set_state(ehci, async, EST_ACTIVE);
2387 94527ead Gerd Hoffmann
            // No break, fall through to ACTIVE
2388 94527ead Gerd Hoffmann
        } else
2389 94527ead Gerd Hoffmann
            break;
2390 94527ead Gerd Hoffmann
2391 94527ead Gerd Hoffmann
    case EST_ACTIVE:
2392 ec807d12 Gerd Hoffmann
        if (!(ehci->frindex & 7) && !ehci_periodic_enabled(ehci)) {
2393 e850c2b4 Hans de Goede
            ehci_queues_rip_all(ehci, async);
2394 26d53979 Gerd Hoffmann
            ehci_set_state(ehci, async, EST_INACTIVE);
2395 94527ead Gerd Hoffmann
            break;
2396 94527ead Gerd Hoffmann
        }
2397 94527ead Gerd Hoffmann
2398 94527ead Gerd Hoffmann
        list = ehci->periodiclistbase & 0xfffff000;
2399 94527ead Gerd Hoffmann
        /* check that register has been set */
2400 94527ead Gerd Hoffmann
        if (list == 0) {
2401 94527ead Gerd Hoffmann
            break;
2402 94527ead Gerd Hoffmann
        }
2403 94527ead Gerd Hoffmann
        list |= ((ehci->frindex & 0x1ff8) >> 1);
2404 94527ead Gerd Hoffmann
2405 4bf80119 David Gibson
        pci_dma_read(&ehci->dev, list, &entry, sizeof entry);
2406 94527ead Gerd Hoffmann
        entry = le32_to_cpu(entry);
2407 94527ead Gerd Hoffmann
2408 94527ead Gerd Hoffmann
        DPRINTF("PERIODIC state adv fr=%d.  [%08X] -> %08X\n",
2409 94527ead Gerd Hoffmann
                ehci->frindex / 8, list, entry);
2410 0122f472 Gerd Hoffmann
        ehci_set_fetch_addr(ehci, async,entry);
2411 26d53979 Gerd Hoffmann
        ehci_set_state(ehci, async, EST_FETCHENTRY);
2412 26d53979 Gerd Hoffmann
        ehci_advance_state(ehci, async);
2413 8f5457eb Hans de Goede
        ehci_queues_rip_unused(ehci, async);
2414 94527ead Gerd Hoffmann
        break;
2415 94527ead Gerd Hoffmann
2416 94527ead Gerd Hoffmann
    default:
2417 94527ead Gerd Hoffmann
        /* this should only be due to a developer mistake */
2418 94527ead Gerd Hoffmann
        fprintf(stderr, "ehci: Bad periodic state %d. "
2419 94527ead Gerd Hoffmann
                "Resetting to active\n", ehci->pstate);
2420 0122f472 Gerd Hoffmann
        assert(0);
2421 94527ead Gerd Hoffmann
    }
2422 94527ead Gerd Hoffmann
}
2423 94527ead Gerd Hoffmann
2424 6ceced0b Gerd Hoffmann
static void ehci_update_frindex(EHCIState *ehci, int frames)
2425 6ceced0b Gerd Hoffmann
{
2426 6ceced0b Gerd Hoffmann
    int i;
2427 6ceced0b Gerd Hoffmann
2428 6ceced0b Gerd Hoffmann
    if (!ehci_enabled(ehci)) {
2429 6ceced0b Gerd Hoffmann
        return;
2430 6ceced0b Gerd Hoffmann
    }
2431 6ceced0b Gerd Hoffmann
2432 6ceced0b Gerd Hoffmann
    for (i = 0; i < frames; i++) {
2433 6ceced0b Gerd Hoffmann
        ehci->frindex += 8;
2434 6ceced0b Gerd Hoffmann
2435 6ceced0b Gerd Hoffmann
        if (ehci->frindex == 0x00002000) {
2436 7efc17af Gerd Hoffmann
            ehci_raise_irq(ehci, USBSTS_FLR);
2437 6ceced0b Gerd Hoffmann
        }
2438 6ceced0b Gerd Hoffmann
2439 6ceced0b Gerd Hoffmann
        if (ehci->frindex == 0x00004000) {
2440 7efc17af Gerd Hoffmann
            ehci_raise_irq(ehci, USBSTS_FLR);
2441 6ceced0b Gerd Hoffmann
            ehci->frindex = 0;
2442 ffa1f2e0 Hans de Goede
            if (ehci->usbsts_frindex >= 0x00004000) {
2443 7efc17af Gerd Hoffmann
                ehci->usbsts_frindex -= 0x00004000;
2444 7efc17af Gerd Hoffmann
            } else {
2445 7efc17af Gerd Hoffmann
                ehci->usbsts_frindex = 0;
2446 7efc17af Gerd Hoffmann
            }
2447 6ceced0b Gerd Hoffmann
        }
2448 6ceced0b Gerd Hoffmann
    }
2449 6ceced0b Gerd Hoffmann
}
2450 6ceced0b Gerd Hoffmann
2451 94527ead Gerd Hoffmann
static void ehci_frame_timer(void *opaque)
2452 94527ead Gerd Hoffmann
{
2453 94527ead Gerd Hoffmann
    EHCIState *ehci = opaque;
2454 7efc17af Gerd Hoffmann
    int need_timer = 0;
2455 94527ead Gerd Hoffmann
    int64_t expire_time, t_now;
2456 adddecb1 Gerd Hoffmann
    uint64_t ns_elapsed;
2457 f020ed36 Gerd Hoffmann
    int frames, skipped_frames;
2458 94527ead Gerd Hoffmann
    int i;
2459 94527ead Gerd Hoffmann
2460 94527ead Gerd Hoffmann
    t_now = qemu_get_clock_ns(vm_clock);
2461 adddecb1 Gerd Hoffmann
    ns_elapsed = t_now - ehci->last_run_ns;
2462 adddecb1 Gerd Hoffmann
    frames = ns_elapsed / FRAME_TIMER_NS;
2463 94527ead Gerd Hoffmann
2464 3a215326 Gerd Hoffmann
    if (ehci_periodic_enabled(ehci) || ehci->pstate != EST_INACTIVE) {
2465 7efc17af Gerd Hoffmann
        need_timer++;
2466 afb7a0b8 Gerd Hoffmann
        ehci->async_stepdown = 0;
2467 94527ead Gerd Hoffmann
2468 f020ed36 Gerd Hoffmann
        if (frames > ehci->maxframes) {
2469 f020ed36 Gerd Hoffmann
            skipped_frames = frames - ehci->maxframes;
2470 f020ed36 Gerd Hoffmann
            ehci_update_frindex(ehci, skipped_frames);
2471 f020ed36 Gerd Hoffmann
            ehci->last_run_ns += FRAME_TIMER_NS * skipped_frames;
2472 f020ed36 Gerd Hoffmann
            frames -= skipped_frames;
2473 f020ed36 Gerd Hoffmann
            DPRINTF("WARNING - EHCI skipped %d frames\n", skipped_frames);
2474 f020ed36 Gerd Hoffmann
        }
2475 f020ed36 Gerd Hoffmann
2476 3a215326 Gerd Hoffmann
        for (i = 0; i < frames; i++) {
2477 8f74ed1e Hans de Goede
            /*
2478 8f74ed1e Hans de Goede
             * If we're running behind schedule, we should not catch up
2479 8f74ed1e Hans de Goede
             * too fast, as that will make some guests unhappy:
2480 8f74ed1e Hans de Goede
             * 1) We must process a minimum of MIN_FR_PER_TICK frames,
2481 8f74ed1e Hans de Goede
             *    otherwise we will never catch up
2482 8f74ed1e Hans de Goede
             * 2) Process frames until the guest has requested an irq (IOC)
2483 8f74ed1e Hans de Goede
             */
2484 8f74ed1e Hans de Goede
            if (i >= MIN_FR_PER_TICK) {
2485 8f74ed1e Hans de Goede
                ehci_commit_irq(ehci);
2486 8f74ed1e Hans de Goede
                if ((ehci->usbsts & USBINTR_MASK) & ehci->usbintr) {
2487 8f74ed1e Hans de Goede
                    break;
2488 8f74ed1e Hans de Goede
                }
2489 8f74ed1e Hans de Goede
            }
2490 3a215326 Gerd Hoffmann
            ehci_update_frindex(ehci, 1);
2491 f020ed36 Gerd Hoffmann
            ehci_advance_periodic_state(ehci);
2492 3a215326 Gerd Hoffmann
            ehci->last_run_ns += FRAME_TIMER_NS;
2493 3a215326 Gerd Hoffmann
        }
2494 3a215326 Gerd Hoffmann
    } else {
2495 3a215326 Gerd Hoffmann
        if (ehci->async_stepdown < ehci->maxframes / 2) {
2496 3a215326 Gerd Hoffmann
            ehci->async_stepdown++;
2497 3a215326 Gerd Hoffmann
        }
2498 3a215326 Gerd Hoffmann
        ehci_update_frindex(ehci, frames);
2499 3a215326 Gerd Hoffmann
        ehci->last_run_ns += FRAME_TIMER_NS * frames;
2500 94527ead Gerd Hoffmann
    }
2501 94527ead Gerd Hoffmann
2502 94527ead Gerd Hoffmann
    /*  Async is not inside loop since it executes everything it can once
2503 94527ead Gerd Hoffmann
     *  called
2504 94527ead Gerd Hoffmann
     */
2505 3a215326 Gerd Hoffmann
    if (ehci_async_enabled(ehci) || ehci->astate != EST_INACTIVE) {
2506 7efc17af Gerd Hoffmann
        need_timer++;
2507 afb7a0b8 Gerd Hoffmann
        ehci_advance_async_state(ehci);
2508 3a215326 Gerd Hoffmann
    }
2509 94527ead Gerd Hoffmann
2510 7efc17af Gerd Hoffmann
    ehci_commit_irq(ehci);
2511 7efc17af Gerd Hoffmann
    if (ehci->usbsts_pending) {
2512 7efc17af Gerd Hoffmann
        need_timer++;
2513 7efc17af Gerd Hoffmann
        ehci->async_stepdown = 0;
2514 daf25307 Gerd Hoffmann
    }
2515 f0ad01f9 Gerd Hoffmann
2516 7efc17af Gerd Hoffmann
    if (need_timer) {
2517 44272b0f Hans de Goede
        /* If we've raised int, we speed up the timer, so that we quickly
2518 44272b0f Hans de Goede
         * notice any new packets queued up in response */
2519 44272b0f Hans de Goede
        if (ehci->int_req_by_async && (ehci->usbsts & USBSTS_INT)) {
2520 44272b0f Hans de Goede
            expire_time = t_now + get_ticks_per_sec() / (FRAME_TIMER_FREQ * 2);
2521 44272b0f Hans de Goede
            ehci->int_req_by_async = false;
2522 44272b0f Hans de Goede
        } else {
2523 44272b0f Hans de Goede
            expire_time = t_now + (get_ticks_per_sec()
2524 afb7a0b8 Gerd Hoffmann
                               * (ehci->async_stepdown+1) / FRAME_TIMER_FREQ);
2525 44272b0f Hans de Goede
        }
2526 7efc17af Gerd Hoffmann
        qemu_mod_timer(ehci->frame_timer, expire_time);
2527 7efc17af Gerd Hoffmann
    }
2528 94527ead Gerd Hoffmann
}
2529 94527ead Gerd Hoffmann
2530 3e4f910c Gerd Hoffmann
static const MemoryRegionOps ehci_mmio_caps_ops = {
2531 3e4f910c Gerd Hoffmann
    .read = ehci_caps_read,
2532 3e4f910c Gerd Hoffmann
    .valid.min_access_size = 1,
2533 3e4f910c Gerd Hoffmann
    .valid.max_access_size = 4,
2534 3e4f910c Gerd Hoffmann
    .impl.min_access_size = 1,
2535 3e4f910c Gerd Hoffmann
    .impl.max_access_size = 1,
2536 3e4f910c Gerd Hoffmann
    .endianness = DEVICE_LITTLE_ENDIAN,
2537 3e4f910c Gerd Hoffmann
};
2538 3e4f910c Gerd Hoffmann
2539 3e4f910c Gerd Hoffmann
static const MemoryRegionOps ehci_mmio_opreg_ops = {
2540 3e4f910c Gerd Hoffmann
    .read = ehci_opreg_read,
2541 3e4f910c Gerd Hoffmann
    .write = ehci_opreg_write,
2542 3e4f910c Gerd Hoffmann
    .valid.min_access_size = 4,
2543 3e4f910c Gerd Hoffmann
    .valid.max_access_size = 4,
2544 3e4f910c Gerd Hoffmann
    .endianness = DEVICE_LITTLE_ENDIAN,
2545 3e4f910c Gerd Hoffmann
};
2546 3e4f910c Gerd Hoffmann
2547 3e4f910c Gerd Hoffmann
static const MemoryRegionOps ehci_mmio_port_ops = {
2548 3e4f910c Gerd Hoffmann
    .read = ehci_port_read,
2549 3e4f910c Gerd Hoffmann
    .write = ehci_port_write,
2550 3e4f910c Gerd Hoffmann
    .valid.min_access_size = 4,
2551 3e4f910c Gerd Hoffmann
    .valid.max_access_size = 4,
2552 e57964f5 Avi Kivity
    .endianness = DEVICE_LITTLE_ENDIAN,
2553 94527ead Gerd Hoffmann
};
2554 94527ead Gerd Hoffmann
2555 94527ead Gerd Hoffmann
static int usb_ehci_initfn(PCIDevice *dev);
2556 94527ead Gerd Hoffmann
2557 94527ead Gerd Hoffmann
static USBPortOps ehci_port_ops = {
2558 94527ead Gerd Hoffmann
    .attach = ehci_attach,
2559 94527ead Gerd Hoffmann
    .detach = ehci_detach,
2560 4706ab6c Hans de Goede
    .child_detach = ehci_child_detach,
2561 a0a3167a Hans de Goede
    .wakeup = ehci_wakeup,
2562 94527ead Gerd Hoffmann
    .complete = ehci_async_complete_packet,
2563 94527ead Gerd Hoffmann
};
2564 94527ead Gerd Hoffmann
2565 07771f6f Gerd Hoffmann
static USBBusOps ehci_bus_ops = {
2566 a0a3167a Hans de Goede
    .register_companion = ehci_register_companion,
2567 07771f6f Gerd Hoffmann
};
2568 07771f6f Gerd Hoffmann
2569 9a773408 Gerd Hoffmann
static int usb_ehci_post_load(void *opaque, int version_id)
2570 9a773408 Gerd Hoffmann
{
2571 9a773408 Gerd Hoffmann
    EHCIState *s = opaque;
2572 9a773408 Gerd Hoffmann
    int i;
2573 9a773408 Gerd Hoffmann
2574 9a773408 Gerd Hoffmann
    for (i = 0; i < NB_PORTS; i++) {
2575 9a773408 Gerd Hoffmann
        USBPort *companion = s->companion_ports[i];
2576 9a773408 Gerd Hoffmann
        if (companion == NULL) {
2577 9a773408 Gerd Hoffmann
            continue;
2578 9a773408 Gerd Hoffmann
        }
2579 9a773408 Gerd Hoffmann
        if (s->portsc[i] & PORTSC_POWNER) {
2580 9a773408 Gerd Hoffmann
            companion->dev = s->ports[i].dev;
2581 9a773408 Gerd Hoffmann
        } else {
2582 9a773408 Gerd Hoffmann
            companion->dev = NULL;
2583 9a773408 Gerd Hoffmann
        }
2584 9a773408 Gerd Hoffmann
    }
2585 9a773408 Gerd Hoffmann
2586 9a773408 Gerd Hoffmann
    return 0;
2587 9a773408 Gerd Hoffmann
}
2588 9a773408 Gerd Hoffmann
2589 ceab6f96 Hans de Goede
static void usb_ehci_vm_state_change(void *opaque, int running, RunState state)
2590 ceab6f96 Hans de Goede
{
2591 ceab6f96 Hans de Goede
    EHCIState *ehci = opaque;
2592 ceab6f96 Hans de Goede
2593 ceab6f96 Hans de Goede
    /*
2594 ceab6f96 Hans de Goede
     * We don't migrate the EHCIQueue-s, instead we rebuild them for the
2595 ceab6f96 Hans de Goede
     * schedule in guest memory. We must do the rebuilt ASAP, so that
2596 ceab6f96 Hans de Goede
     * USB-devices which have async handled packages have a packet in the
2597 ceab6f96 Hans de Goede
     * ep queue to match the completion with.
2598 ceab6f96 Hans de Goede
     */
2599 ceab6f96 Hans de Goede
    if (state == RUN_STATE_RUNNING) {
2600 ceab6f96 Hans de Goede
        ehci_advance_async_state(ehci);
2601 ceab6f96 Hans de Goede
    }
2602 ceab6f96 Hans de Goede
2603 ceab6f96 Hans de Goede
    /*
2604 ceab6f96 Hans de Goede
     * The schedule rebuilt from guest memory could cause the migration dest
2605 ceab6f96 Hans de Goede
     * to miss a QH unlink, and fail to cancel packets, since the unlinked QH
2606 ceab6f96 Hans de Goede
     * will never have existed on the destination. Therefor we must flush the
2607 ceab6f96 Hans de Goede
     * async schedule on savevm to catch any not yet noticed unlinks.
2608 ceab6f96 Hans de Goede
     */
2609 ceab6f96 Hans de Goede
    if (state == RUN_STATE_SAVE_VM) {
2610 ceab6f96 Hans de Goede
        ehci_advance_async_state(ehci);
2611 ceab6f96 Hans de Goede
        ehci_queues_rip_unseen(ehci, 1);
2612 ceab6f96 Hans de Goede
    }
2613 ceab6f96 Hans de Goede
}
2614 ceab6f96 Hans de Goede
2615 9490fb06 Gerd Hoffmann
static const VMStateDescription vmstate_ehci = {
2616 9a773408 Gerd Hoffmann
    .name        = "ehci",
2617 6d3b6d3d Gerd Hoffmann
    .version_id  = 2,
2618 6d3b6d3d Gerd Hoffmann
    .minimum_version_id  = 1,
2619 9a773408 Gerd Hoffmann
    .post_load   = usb_ehci_post_load,
2620 9a773408 Gerd Hoffmann
    .fields      = (VMStateField[]) {
2621 9a773408 Gerd Hoffmann
        VMSTATE_PCI_DEVICE(dev, EHCIState),
2622 9a773408 Gerd Hoffmann
        /* mmio registers */
2623 9a773408 Gerd Hoffmann
        VMSTATE_UINT32(usbcmd, EHCIState),
2624 9a773408 Gerd Hoffmann
        VMSTATE_UINT32(usbsts, EHCIState),
2625 6d3b6d3d Gerd Hoffmann
        VMSTATE_UINT32_V(usbsts_pending, EHCIState, 2),
2626 6d3b6d3d Gerd Hoffmann
        VMSTATE_UINT32_V(usbsts_frindex, EHCIState, 2),
2627 9a773408 Gerd Hoffmann
        VMSTATE_UINT32(usbintr, EHCIState),
2628 9a773408 Gerd Hoffmann
        VMSTATE_UINT32(frindex, EHCIState),
2629 9a773408 Gerd Hoffmann
        VMSTATE_UINT32(ctrldssegment, EHCIState),
2630 9a773408 Gerd Hoffmann
        VMSTATE_UINT32(periodiclistbase, EHCIState),
2631 9a773408 Gerd Hoffmann
        VMSTATE_UINT32(asynclistaddr, EHCIState),
2632 9a773408 Gerd Hoffmann
        VMSTATE_UINT32(configflag, EHCIState),
2633 9a773408 Gerd Hoffmann
        VMSTATE_UINT32(portsc[0], EHCIState),
2634 9a773408 Gerd Hoffmann
        VMSTATE_UINT32(portsc[1], EHCIState),
2635 9a773408 Gerd Hoffmann
        VMSTATE_UINT32(portsc[2], EHCIState),
2636 9a773408 Gerd Hoffmann
        VMSTATE_UINT32(portsc[3], EHCIState),
2637 9a773408 Gerd Hoffmann
        VMSTATE_UINT32(portsc[4], EHCIState),
2638 9a773408 Gerd Hoffmann
        VMSTATE_UINT32(portsc[5], EHCIState),
2639 9a773408 Gerd Hoffmann
        /* frame timer */
2640 9a773408 Gerd Hoffmann
        VMSTATE_TIMER(frame_timer, EHCIState),
2641 9a773408 Gerd Hoffmann
        VMSTATE_UINT64(last_run_ns, EHCIState),
2642 9a773408 Gerd Hoffmann
        VMSTATE_UINT32(async_stepdown, EHCIState),
2643 9a773408 Gerd Hoffmann
        /* schedule state */
2644 9a773408 Gerd Hoffmann
        VMSTATE_UINT32(astate, EHCIState),
2645 9a773408 Gerd Hoffmann
        VMSTATE_UINT32(pstate, EHCIState),
2646 9a773408 Gerd Hoffmann
        VMSTATE_UINT32(a_fetch_addr, EHCIState),
2647 9a773408 Gerd Hoffmann
        VMSTATE_UINT32(p_fetch_addr, EHCIState),
2648 9a773408 Gerd Hoffmann
        VMSTATE_END_OF_LIST()
2649 9a773408 Gerd Hoffmann
    }
2650 9490fb06 Gerd Hoffmann
};
2651 9490fb06 Gerd Hoffmann
2652 3028376e Gerd Hoffmann
static Property ehci_properties[] = {
2653 3028376e Gerd Hoffmann
    DEFINE_PROP_UINT32("maxframes", EHCIState, maxframes, 128),
2654 3028376e Gerd Hoffmann
    DEFINE_PROP_END_OF_LIST(),
2655 3028376e Gerd Hoffmann
};
2656 3028376e Gerd Hoffmann
2657 40021f08 Anthony Liguori
static void ehci_class_init(ObjectClass *klass, void *data)
2658 40021f08 Anthony Liguori
{
2659 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
2660 40021f08 Anthony Liguori
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
2661 40021f08 Anthony Liguori
2662 40021f08 Anthony Liguori
    k->init = usb_ehci_initfn;
2663 40021f08 Anthony Liguori
    k->vendor_id = PCI_VENDOR_ID_INTEL;
2664 40021f08 Anthony Liguori
    k->device_id = PCI_DEVICE_ID_INTEL_82801D; /* ich4 */
2665 40021f08 Anthony Liguori
    k->revision = 0x10;
2666 40021f08 Anthony Liguori
    k->class_id = PCI_CLASS_SERIAL_USB;
2667 39bffca2 Anthony Liguori
    dc->vmsd = &vmstate_ehci;
2668 39bffca2 Anthony Liguori
    dc->props = ehci_properties;
2669 40021f08 Anthony Liguori
}
2670 40021f08 Anthony Liguori
2671 39bffca2 Anthony Liguori
static TypeInfo ehci_info = {
2672 39bffca2 Anthony Liguori
    .name          = "usb-ehci",
2673 39bffca2 Anthony Liguori
    .parent        = TYPE_PCI_DEVICE,
2674 39bffca2 Anthony Liguori
    .instance_size = sizeof(EHCIState),
2675 39bffca2 Anthony Liguori
    .class_init    = ehci_class_init,
2676 e855761c Anthony Liguori
};
2677 e855761c Anthony Liguori
2678 40021f08 Anthony Liguori
static void ich9_ehci_class_init(ObjectClass *klass, void *data)
2679 40021f08 Anthony Liguori
{
2680 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
2681 40021f08 Anthony Liguori
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
2682 40021f08 Anthony Liguori
2683 40021f08 Anthony Liguori
    k->init = usb_ehci_initfn;
2684 40021f08 Anthony Liguori
    k->vendor_id = PCI_VENDOR_ID_INTEL;
2685 40021f08 Anthony Liguori
    k->device_id = PCI_DEVICE_ID_INTEL_82801I_EHCI1;
2686 40021f08 Anthony Liguori
    k->revision = 0x03;
2687 40021f08 Anthony Liguori
    k->class_id = PCI_CLASS_SERIAL_USB;
2688 39bffca2 Anthony Liguori
    dc->vmsd = &vmstate_ehci;
2689 39bffca2 Anthony Liguori
    dc->props = ehci_properties;
2690 40021f08 Anthony Liguori
}
2691 40021f08 Anthony Liguori
2692 39bffca2 Anthony Liguori
static TypeInfo ich9_ehci_info = {
2693 39bffca2 Anthony Liguori
    .name          = "ich9-usb-ehci1",
2694 39bffca2 Anthony Liguori
    .parent        = TYPE_PCI_DEVICE,
2695 39bffca2 Anthony Liguori
    .instance_size = sizeof(EHCIState),
2696 39bffca2 Anthony Liguori
    .class_init    = ich9_ehci_class_init,
2697 94527ead Gerd Hoffmann
};
2698 94527ead Gerd Hoffmann
2699 94527ead Gerd Hoffmann
static int usb_ehci_initfn(PCIDevice *dev)
2700 94527ead Gerd Hoffmann
{
2701 94527ead Gerd Hoffmann
    EHCIState *s = DO_UPCAST(EHCIState, dev, dev);
2702 94527ead Gerd Hoffmann
    uint8_t *pci_conf = s->dev.config;
2703 94527ead Gerd Hoffmann
    int i;
2704 94527ead Gerd Hoffmann
2705 94527ead Gerd Hoffmann
    pci_set_byte(&pci_conf[PCI_CLASS_PROG], 0x20);
2706 94527ead Gerd Hoffmann
2707 94527ead Gerd Hoffmann
    /* capabilities pointer */
2708 94527ead Gerd Hoffmann
    pci_set_byte(&pci_conf[PCI_CAPABILITY_LIST], 0x00);
2709 94527ead Gerd Hoffmann
    //pci_set_byte(&pci_conf[PCI_CAPABILITY_LIST], 0x50);
2710 94527ead Gerd Hoffmann
2711 817e0b6f Michael S. Tsirkin
    pci_set_byte(&pci_conf[PCI_INTERRUPT_PIN], 4); /* interrupt pin D */
2712 94527ead Gerd Hoffmann
    pci_set_byte(&pci_conf[PCI_MIN_GNT], 0);
2713 94527ead Gerd Hoffmann
    pci_set_byte(&pci_conf[PCI_MAX_LAT], 0);
2714 94527ead Gerd Hoffmann
2715 94527ead Gerd Hoffmann
    // pci_conf[0x50] = 0x01; // power management caps
2716 94527ead Gerd Hoffmann
2717 4001f22f Brad Hards
    pci_set_byte(&pci_conf[USB_SBRN], USB_RELEASE_2); // release number (2.1.4)
2718 94527ead Gerd Hoffmann
    pci_set_byte(&pci_conf[0x61], 0x20);  // frame length adjustment (2.1.5)
2719 94527ead Gerd Hoffmann
    pci_set_word(&pci_conf[0x62], 0x00);  // port wake up capability (2.1.6)
2720 94527ead Gerd Hoffmann
2721 94527ead Gerd Hoffmann
    pci_conf[0x64] = 0x00;
2722 94527ead Gerd Hoffmann
    pci_conf[0x65] = 0x00;
2723 94527ead Gerd Hoffmann
    pci_conf[0x66] = 0x00;
2724 94527ead Gerd Hoffmann
    pci_conf[0x67] = 0x00;
2725 94527ead Gerd Hoffmann
    pci_conf[0x68] = 0x01;
2726 94527ead Gerd Hoffmann
    pci_conf[0x69] = 0x00;
2727 94527ead Gerd Hoffmann
    pci_conf[0x6a] = 0x00;
2728 94527ead Gerd Hoffmann
    pci_conf[0x6b] = 0x00;  // USBLEGSUP
2729 94527ead Gerd Hoffmann
    pci_conf[0x6c] = 0x00;
2730 94527ead Gerd Hoffmann
    pci_conf[0x6d] = 0x00;
2731 94527ead Gerd Hoffmann
    pci_conf[0x6e] = 0x00;
2732 94527ead Gerd Hoffmann
    pci_conf[0x6f] = 0xc0;  // USBLEFCTLSTS
2733 94527ead Gerd Hoffmann
2734 3e4f910c Gerd Hoffmann
    /* 2.2 host controller interface version */
2735 3e4f910c Gerd Hoffmann
    s->caps[0x00] = (uint8_t) OPREGBASE;
2736 3e4f910c Gerd Hoffmann
    s->caps[0x01] = 0x00;
2737 3e4f910c Gerd Hoffmann
    s->caps[0x02] = 0x00;
2738 3e4f910c Gerd Hoffmann
    s->caps[0x03] = 0x01;        /* HC version */
2739 3e4f910c Gerd Hoffmann
    s->caps[0x04] = NB_PORTS;    /* Number of downstream ports */
2740 3e4f910c Gerd Hoffmann
    s->caps[0x05] = 0x00;        /* No companion ports at present */
2741 3e4f910c Gerd Hoffmann
    s->caps[0x06] = 0x00;
2742 3e4f910c Gerd Hoffmann
    s->caps[0x07] = 0x00;
2743 3e4f910c Gerd Hoffmann
    s->caps[0x08] = 0x80;        /* We can cache whole frame, no 64-bit */
2744 3e4f910c Gerd Hoffmann
    s->caps[0x09] = 0x68;        /* EECP */
2745 3e4f910c Gerd Hoffmann
    s->caps[0x0a] = 0x00;
2746 3e4f910c Gerd Hoffmann
    s->caps[0x0b] = 0x00;
2747 94527ead Gerd Hoffmann
2748 94527ead Gerd Hoffmann
    s->irq = s->dev.irq[3];
2749 94527ead Gerd Hoffmann
2750 07771f6f Gerd Hoffmann
    usb_bus_new(&s->bus, &ehci_bus_ops, &s->dev.qdev);
2751 94527ead Gerd Hoffmann
    for(i = 0; i < NB_PORTS; i++) {
2752 94527ead Gerd Hoffmann
        usb_register_port(&s->bus, &s->ports[i], s, i, &ehci_port_ops,
2753 94527ead Gerd Hoffmann
                          USB_SPEED_MASK_HIGH);
2754 94527ead Gerd Hoffmann
        s->ports[i].dev = 0;
2755 94527ead Gerd Hoffmann
    }
2756 94527ead Gerd Hoffmann
2757 94527ead Gerd Hoffmann
    s->frame_timer = qemu_new_timer_ns(vm_clock, ehci_frame_timer, s);
2758 0262f65a Hans de Goede
    s->async_bh = qemu_bh_new(ehci_frame_timer, s);
2759 df5d5c5c Hans de Goede
    QTAILQ_INIT(&s->aqueues);
2760 df5d5c5c Hans de Goede
    QTAILQ_INIT(&s->pqueues);
2761 7341ea07 Hans de Goede
    usb_packet_init(&s->ipacket);
2762 94527ead Gerd Hoffmann
2763 94527ead Gerd Hoffmann
    qemu_register_reset(ehci_reset, s);
2764 ceab6f96 Hans de Goede
    qemu_add_vm_change_state_handler(usb_ehci_vm_state_change, s);
2765 94527ead Gerd Hoffmann
2766 3e4f910c Gerd Hoffmann
    memory_region_init(&s->mem, "ehci", MMIO_SIZE);
2767 3e4f910c Gerd Hoffmann
    memory_region_init_io(&s->mem_caps, &ehci_mmio_caps_ops, s,
2768 3e4f910c Gerd Hoffmann
                          "capabilities", OPREGBASE);
2769 3e4f910c Gerd Hoffmann
    memory_region_init_io(&s->mem_opreg, &ehci_mmio_opreg_ops, s,
2770 3e4f910c Gerd Hoffmann
                          "operational", PORTSC_BEGIN - OPREGBASE);
2771 3e4f910c Gerd Hoffmann
    memory_region_init_io(&s->mem_ports, &ehci_mmio_port_ops, s,
2772 3e4f910c Gerd Hoffmann
                          "ports", PORTSC_END - PORTSC_BEGIN);
2773 3e4f910c Gerd Hoffmann
2774 3e4f910c Gerd Hoffmann
    memory_region_add_subregion(&s->mem, 0,            &s->mem_caps);
2775 3e4f910c Gerd Hoffmann
    memory_region_add_subregion(&s->mem, OPREGBASE,    &s->mem_opreg);
2776 3e4f910c Gerd Hoffmann
    memory_region_add_subregion(&s->mem, PORTSC_BEGIN, &s->mem_ports);
2777 3e4f910c Gerd Hoffmann
2778 e824b2cc Avi Kivity
    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mem);
2779 94527ead Gerd Hoffmann
2780 94527ead Gerd Hoffmann
    return 0;
2781 94527ead Gerd Hoffmann
}
2782 94527ead Gerd Hoffmann
2783 83f7d43a Andreas Färber
static void ehci_register_types(void)
2784 94527ead Gerd Hoffmann
{
2785 39bffca2 Anthony Liguori
    type_register_static(&ehci_info);
2786 39bffca2 Anthony Liguori
    type_register_static(&ich9_ehci_info);
2787 94527ead Gerd Hoffmann
}
2788 83f7d43a Andreas Färber
2789 83f7d43a Andreas Färber
type_init(ehci_register_types)
2790 94527ead Gerd Hoffmann
2791 94527ead Gerd Hoffmann
/*
2792 94527ead Gerd Hoffmann
 * vim: expandtab ts=4
2793 94527ead Gerd Hoffmann
 */