1 |
2 |
dimamali |
/*
|
2 |
|
|
* Tests for GRUSBHC
|
3 |
|
|
*
|
4 |
|
|
* Copyright (c) 2008 Gaisler Research AB
|
5 |
|
|
*
|
6 |
|
|
* Test functions:
|
7 |
|
|
* ehc_test(..): Tests EHC only
|
8 |
|
|
* uhc_test(..): Tests UHC only
|
9 |
|
|
* grusbhc_test(..): Tests UHC by calling uhc_test(..), then tests EHC by calling
|
10 |
|
|
* ehc_test(..). If a address argument for a controller is 0 the
|
11 |
|
|
* test for that controller will be skipped.
|
12 |
|
|
*
|
13 |
|
|
* This test application transfers data but skips device resets and enumeration.
|
14 |
|
|
* It will not work with a real USB device.
|
15 |
|
|
*
|
16 |
|
|
* Requirements on simulation environment:
|
17 |
|
|
* All ports must be connected to the utmi or ulpi simulation model
|
18 |
|
|
* available in the gaisler simulation library lib/gaisler/sim.
|
19 |
|
|
*/
|
20 |
|
|
|
21 |
|
|
#include "testmod.h"
|
22 |
|
|
#include <malloc.h>
|
23 |
|
|
|
24 |
|
|
/***********/
|
25 |
|
|
/* Helpers */
|
26 |
|
|
/***********/
|
27 |
|
|
|
28 |
|
|
#define byte_swap(x) ((((x) >> 24) & 0xff) | (((x) >> 8) & 0xff00) | \
|
29 |
|
|
(((x) << 8) & 0xff0000) | ((x) << 24))
|
30 |
|
|
|
31 |
|
|
#define cond_bswap(x, be) (be ? (x) : byte_swap(x))
|
32 |
|
|
|
33 |
|
|
#define hword_swap(x) ((((x) >> 16) & 0xffff) | ((x) << 16))
|
34 |
|
|
|
35 |
|
|
|
36 |
|
|
int *build_frame_list(int nelem, int bedesc)
|
37 |
|
|
{
|
38 |
|
|
int i;
|
39 |
|
|
int *flbase;
|
40 |
|
|
|
41 |
|
|
flbase = memalign(4096, nelem*4);
|
42 |
|
|
|
43 |
|
|
for (i = 0; i < nelem; i++)
|
44 |
|
|
if (bedesc = 1)
|
45 |
|
|
*(flbase + i) = 1;
|
46 |
|
|
else
|
47 |
|
|
*(flbase + i) = 0x01000000;
|
48 |
|
|
|
49 |
|
|
return flbase;
|
50 |
|
|
}
|
51 |
|
|
|
52 |
|
|
/*********************/
|
53 |
|
|
/* EHC specific code */
|
54 |
|
|
/*********************/
|
55 |
|
|
|
56 |
|
|
/* Register fields */
|
57 |
|
|
/* USBCMD */
|
58 |
|
|
#define EHC_USBCMD_ITHRES (0xff << 16)
|
59 |
|
|
#define EHC_USBCMD_ITHRES_P 16
|
60 |
|
|
#define EHC_USBCMD_PMODE (1 << 11)
|
61 |
|
|
#define EHC_USBCMD_PMODECNT (3 << 8)
|
62 |
|
|
#define EHC_USBCMD_LHCRESET (1 << 7)
|
63 |
|
|
#define EHC_USBCMD_AS_ADV_INT (1 << 6)
|
64 |
|
|
#define EHC_USBCMD_AS_SCHED_EN (1 << 5)
|
65 |
|
|
#define EHC_USBCMD_PER_SCHED_EN (1 << 4)
|
66 |
|
|
#define EHC_USBCMD_FLSIZE (3 << 2)
|
67 |
|
|
#define EHC_USBCMD_HCRESET (1 << 1)
|
68 |
|
|
#define EHC_USBCMD_RUNSTOP (1 << 0)
|
69 |
|
|
|
70 |
|
|
/* USBSTS */
|
71 |
|
|
#define EHC_USBSTS_ASSTAT (1 << 15)
|
72 |
|
|
#define EHC_USBSTS_PERSTAT (1 << 14)
|
73 |
|
|
#define EHC_USBSTS_RECL (1 << 13)
|
74 |
|
|
#define EHC_USBSTS_HCHALTED (1 << 12)
|
75 |
|
|
#define EHC_USBSTS_ASADV (1 << 5)
|
76 |
|
|
#define EHC_USBSTS_HSERR (1 << 4)
|
77 |
|
|
#define EHC_USBSTS_FLROLL (1 << 3)
|
78 |
|
|
#define EHC_USBSTS_PCHANGE_DETECT (1 << 2)
|
79 |
|
|
#define EHC_USBSTS_USBERRINT (1 << 1)
|
80 |
|
|
#define EHC_USBSTS_USBINT (1 << 0)
|
81 |
|
|
|
82 |
|
|
/* CONFIGFLAG */
|
83 |
|
|
#define EHC_CONFIGFLAG_CF (1 << 0)
|
84 |
|
|
|
85 |
|
|
/* PORTSC */
|
86 |
|
|
#define EHC_PORTSC_WKOC_E (1 << 22)
|
87 |
|
|
#define EHC_PORTSC_WKDSCNNT_E (1 << 21)
|
88 |
|
|
#define EHC_PORTSC_WKCNNT_E (1 << 20)
|
89 |
|
|
#define EHC_PORTSC_POWNER (1 << 13)
|
90 |
|
|
#define EHC_PORTSC_PP (1 << 12)
|
91 |
|
|
#define EHC_PORTSC_LS_P 10
|
92 |
|
|
#define EHC_PORTSC_PRESET (1 << 8)
|
93 |
|
|
#define EHC_PORTSC_PSUSPEND (1 << 7)
|
94 |
|
|
#define EHC_PORTSC_PRESUME (1 << 6)
|
95 |
|
|
#define EHC_PORTSC_OC_CHANGE (1 << 5)
|
96 |
|
|
#define EHC_PORTSC_OC_ACTIVE (1 << 4)
|
97 |
|
|
#define EHC_PORTSC_PEN_CHANGE (1 << 3)
|
98 |
|
|
#define EHC_PORTSC_PEN (1 << 2)
|
99 |
|
|
#define EHC_PORTSC_CNNTSTAT_CHANGE (1 << 1)
|
100 |
|
|
#define EHC_PORTSC_CNNTSTAT (1 << 0)
|
101 |
|
|
|
102 |
|
|
#define EHC_JSTATE 0x2
|
103 |
|
|
|
104 |
|
|
#define EHC_AUXREGS_OFF 0x54
|
105 |
|
|
|
106 |
|
|
#define EHC_USBCMD_RESVAL(aspm) (aspm ? 0x00080b00 : 0x00080000)
|
107 |
|
|
#define EHC_USBSTS_RESVAL 0x00001000
|
108 |
|
|
#define EHC_USBINTR_RESVAL 0x00000000
|
109 |
|
|
#define EHC_FRINDEX_RESVAL 0x00000000
|
110 |
|
|
#define EHC_CTRLDSSEGMENT_RESVAL 0x00000000
|
111 |
|
|
#define EHC_CONFIGFLAG_RESVAL 0x00000000
|
112 |
|
|
#define EHC_PORTSC_RESVAL(ppc) (ppc ? 0x00002000 : 0x00003000)
|
113 |
|
|
|
114 |
|
|
#define EHC_HCSPARAMS_NPORTS(x) (x & 0xf)
|
115 |
|
|
#define EHC_HCSPARAMS_PPC(x) (x & 0x10)
|
116 |
|
|
|
117 |
|
|
#define EHC_HCCPARAMS_ASPM(x) (x & 0x4)
|
118 |
|
|
|
119 |
|
|
struct ehccoreregs {
|
120 |
|
|
volatile unsigned int capver;
|
121 |
|
|
volatile unsigned int hcsparams;
|
122 |
|
|
volatile unsigned int hccparams;
|
123 |
|
|
volatile unsigned int hcspportroute[2];
|
124 |
|
|
volatile unsigned int usbcmd;
|
125 |
|
|
volatile unsigned int usbsts;
|
126 |
|
|
volatile unsigned int usbintr;
|
127 |
|
|
volatile unsigned int frindex;
|
128 |
|
|
volatile unsigned int ctrldssegment;
|
129 |
|
|
volatile unsigned int perlistbase;
|
130 |
|
|
volatile unsigned int alistaddr;
|
131 |
|
|
};
|
132 |
|
|
|
133 |
|
|
struct ehcauxregs {
|
134 |
|
|
volatile unsigned int configflag;
|
135 |
|
|
volatile unsigned int portsc[15];
|
136 |
|
|
};
|
137 |
|
|
|
138 |
|
|
/* Descriptor fields and helper defines */
|
139 |
|
|
|
140 |
|
|
#define EHC_TYP_iTD 0x00
|
141 |
|
|
#define EHC_TYP_QH 0x02
|
142 |
|
|
#define EHC_T (1 << 0)
|
143 |
|
|
|
144 |
|
|
#define EHC_HS 2
|
145 |
|
|
|
146 |
|
|
#define iTD_STATUS_P 28
|
147 |
|
|
#define iTD_ACTIVE (1 << 3)
|
148 |
|
|
#define iTD_TLEN_P 16
|
149 |
|
|
#define iTD_IOC (1 << 15)
|
150 |
|
|
#define iTD_IO (1 << 11)
|
151 |
|
|
|
152 |
|
|
#define QH_RL_P 28
|
153 |
|
|
#define QH_C (1 << 27)
|
154 |
|
|
#define QH_MAXP_P 16
|
155 |
|
|
#define QH_H (1 << 15)
|
156 |
|
|
#define QH_DTC (1 << 14)
|
157 |
|
|
#define QH_EPS_P 12
|
158 |
|
|
#define QH_ENDPT_P 8
|
159 |
|
|
#define QH_MULT_P 30
|
160 |
|
|
|
161 |
|
|
#define qTD_DT (1 << 31)
|
162 |
|
|
#define qTD_TOTALB_P 16
|
163 |
|
|
#define qTD_IOC (1 << 15)
|
164 |
|
|
#define qTD_PID_P 8
|
165 |
|
|
#define qTD_ACTIVE 0x80
|
166 |
|
|
#define qTD_HALTBABXACT 0x58
|
167 |
|
|
|
168 |
|
|
#define qTD_OUT 0
|
169 |
|
|
#define qTD_IN 1
|
170 |
|
|
#define qTD_SETUP 10
|
171 |
|
|
|
172 |
|
|
#define MASK_UFRAME0 0x01
|
173 |
|
|
#define MASK_UFRAME1 0x02
|
174 |
|
|
|
175 |
|
|
|
176 |
|
|
struct ehc_itd {
|
177 |
|
|
volatile unsigned int lp;
|
178 |
|
|
volatile unsigned int status[8];
|
179 |
|
|
volatile unsigned int buf[7];
|
180 |
|
|
};
|
181 |
|
|
|
182 |
|
|
struct ehc_qtd {
|
183 |
|
|
volatile unsigned int next;
|
184 |
|
|
volatile unsigned int anext;
|
185 |
|
|
volatile unsigned int token;
|
186 |
|
|
volatile unsigned int bufp[4];
|
187 |
|
|
|
188 |
|
|
};
|
189 |
|
|
|
190 |
|
|
struct ehc_qh {
|
191 |
|
|
volatile unsigned int lp;
|
192 |
|
|
volatile unsigned int chr;
|
193 |
|
|
volatile unsigned int cap;
|
194 |
|
|
volatile unsigned int curr;
|
195 |
|
|
struct ehc_qtd qtd;
|
196 |
|
|
};
|
197 |
|
|
|
198 |
|
|
|
199 |
|
|
void ehc_check_opresvals(struct ehccoreregs *c, struct ehcauxregs *a,
|
200 |
|
|
int beregs)
|
201 |
|
|
{
|
202 |
|
|
int i = 0;
|
203 |
|
|
int nports = EHC_HCSPARAMS_NPORTS(cond_bswap(c->hcsparams,beregs));
|
204 |
|
|
int aspm = EHC_HCCPARAMS_ASPM(cond_bswap(c->hccparams,beregs));
|
205 |
|
|
int ppc = EHC_HCSPARAMS_PPC(cond_bswap(c->hcsparams,beregs));
|
206 |
|
|
|
207 |
|
|
if (c->usbcmd != cond_bswap(EHC_USBCMD_RESVAL(aspm),beregs))
|
208 |
|
|
fail(0);
|
209 |
|
|
if (c->usbsts != cond_bswap(EHC_USBSTS_RESVAL,beregs))
|
210 |
|
|
fail(1);
|
211 |
|
|
if (c->usbintr != cond_bswap(EHC_USBINTR_RESVAL,beregs))
|
212 |
|
|
fail(2);
|
213 |
|
|
if (c->frindex != cond_bswap(EHC_FRINDEX_RESVAL,beregs))
|
214 |
|
|
fail(3);
|
215 |
|
|
if (c->ctrldssegment != cond_bswap(EHC_CTRLDSSEGMENT_RESVAL,beregs))
|
216 |
|
|
fail(4);
|
217 |
|
|
/* Periodic List Base has undefined reset value, not checked */
|
218 |
|
|
/* Asynchronous List Address has undefined reset value, not checked */
|
219 |
|
|
if (a->configflag != cond_bswap(EHC_CONFIGFLAG_RESVAL,beregs))
|
220 |
|
|
fail(5);
|
221 |
|
|
while (i < nports) {
|
222 |
|
|
if (a->portsc[i] != cond_bswap(EHC_PORTSC_RESVAL(ppc),beregs))
|
223 |
|
|
fail(6+i);
|
224 |
|
|
i++;
|
225 |
|
|
}
|
226 |
|
|
}
|
227 |
|
|
|
228 |
|
|
|
229 |
|
|
int ehc_test(int addr, int bedesc, int beregs)
|
230 |
|
|
{
|
231 |
|
|
int i;
|
232 |
|
|
|
233 |
|
|
char *buf;
|
234 |
|
|
int *flbase;
|
235 |
|
|
|
236 |
|
|
struct ehccoreregs *c;
|
237 |
|
|
struct ehcauxregs *a;
|
238 |
|
|
|
239 |
|
|
struct ehc_itd *itdi, *itdo;
|
240 |
|
|
struct ehc_qh *qhi, *qho, *aqh;
|
241 |
|
|
struct ehc_qtd *qtdi, *qtdo, *aqtdi, *aqtdo;
|
242 |
|
|
|
243 |
|
|
|
244 |
|
|
report_device(0x01026000);
|
245 |
|
|
|
246 |
|
|
c = (struct ehccoreregs*)addr;
|
247 |
|
|
a = (struct ehcauxregs*)(addr + EHC_AUXREGS_OFF);
|
248 |
|
|
|
249 |
|
|
/* Check register reset values */
|
250 |
|
|
report_subtest(1);
|
251 |
|
|
|
252 |
|
|
ehc_check_opresvals(c, a, beregs);
|
253 |
|
|
|
254 |
|
|
/* Perform HC Reset */
|
255 |
|
|
report_subtest(2);
|
256 |
|
|
|
257 |
|
|
c->usbcmd |= cond_bswap(EHC_USBCMD_HCRESET, beregs);
|
258 |
|
|
|
259 |
|
|
while (c->usbcmd & cond_bswap(EHC_USBCMD_HCRESET,beregs))
|
260 |
|
|
;
|
261 |
|
|
|
262 |
|
|
ehc_check_opresvals(c, a, beregs);
|
263 |
|
|
|
264 |
|
|
/* Activate controller, reset device and transfer 1 byte isoch OUT and IN,
|
265 |
|
|
1 byte interrupt OUT and IN */
|
266 |
|
|
report_subtest(3);
|
267 |
|
|
|
268 |
|
|
a->configflag = cond_bswap(EHC_CONFIGFLAG_CF,beregs);
|
269 |
|
|
|
270 |
|
|
if (EHC_HCSPARAMS_PPC(cond_bswap(c->hcsparams,beregs)))
|
271 |
|
|
a->portsc[0] = cond_bswap(EHC_PORTSC_PP, beregs);
|
272 |
|
|
|
273 |
|
|
while (!(a->portsc[0] & cond_bswap(EHC_PORTSC_CNNTSTAT, beregs)))
|
274 |
|
|
;
|
275 |
|
|
|
276 |
|
|
/* Controller should discover connect */
|
277 |
|
|
if (a->portsc[0] != cond_bswap(EHC_PORTSC_PP |
|
278 |
|
|
(EHC_JSTATE << EHC_PORTSC_LS_P) |
|
279 |
|
|
EHC_PORTSC_CNNTSTAT_CHANGE |
|
280 |
|
|
EHC_PORTSC_CNNTSTAT, beregs))
|
281 |
|
|
fail(0);
|
282 |
|
|
|
283 |
|
|
a->portsc[0] |= cond_bswap(EHC_PORTSC_PRESET,beregs);
|
284 |
|
|
|
285 |
|
|
/* Build schedule */
|
286 |
|
|
flbase = build_frame_list(2, bedesc);
|
287 |
|
|
|
288 |
|
|
if ((itdi = memalign(32, sizeof(struct ehc_itd))) == NULL)
|
289 |
|
|
fail(1);
|
290 |
|
|
if ((itdo = memalign(32, sizeof(struct ehc_itd))) == NULL)
|
291 |
|
|
fail(2);
|
292 |
|
|
if ((qhi = memalign(32, sizeof(struct ehc_qh))) == NULL)
|
293 |
|
|
fail(3);
|
294 |
|
|
if ((qho = memalign(32, sizeof(struct ehc_qh))) == NULL)
|
295 |
|
|
fail(4);
|
296 |
|
|
if ((qtdi = memalign(32, sizeof(struct ehc_qtd))) == NULL)
|
297 |
|
|
fail(5);
|
298 |
|
|
if ((qtdo = memalign(32, sizeof(struct ehc_qtd))) == NULL)
|
299 |
|
|
fail(6);
|
300 |
|
|
|
301 |
|
|
if ((buf = memalign(4096, 2)) == NULL)
|
302 |
|
|
fail(7);
|
303 |
|
|
|
304 |
|
|
*buf = 0xaa;
|
305 |
|
|
*(buf+1) = 0xbb;
|
306 |
|
|
|
307 |
|
|
itdo->lp = cond_bswap((int)itdi,bedesc);
|
308 |
|
|
itdo->status[0] = cond_bswap((iTD_ACTIVE << iTD_STATUS_P) |
|
309 |
|
|
(1 << iTD_TLEN_P),bedesc);
|
310 |
|
|
for (i = 1; i < 8; i++)
|
311 |
|
|
itdo->status[i] = 0;
|
312 |
|
|
itdo->buf[0] = cond_bswap((int)buf,bedesc);
|
313 |
|
|
itdo->buf[1] = cond_bswap(1,bedesc);
|
314 |
|
|
itdo->buf[2] = cond_bswap(1,bedesc);
|
315 |
|
|
itdi->lp = cond_bswap((int)qho | EHC_TYP_QH ,bedesc);
|
316 |
|
|
itdi->status[0] = cond_bswap((iTD_ACTIVE << iTD_STATUS_P) |
|
317 |
|
|
(1 << iTD_TLEN_P),bedesc);
|
318 |
|
|
for (i = 1; i < 8; i++)
|
319 |
|
|
itdi->status[i] = 0;
|
320 |
|
|
itdi->buf[0] = cond_bswap((int)buf,bedesc);
|
321 |
|
|
itdi->buf[1] = cond_bswap(iTD_IO | 1,bedesc);
|
322 |
|
|
itdi->buf[2] = cond_bswap(1,bedesc);
|
323 |
|
|
|
324 |
|
|
qho->lp = cond_bswap((int)qhi | EHC_TYP_QH,bedesc);
|
325 |
|
|
qho->chr = cond_bswap((1 << QH_MAXP_P) | (EHC_HS << QH_EPS_P) |
|
326 |
|
|
(1 << QH_ENDPT_P),bedesc);
|
327 |
|
|
qho->cap = cond_bswap(1 << QH_MULT_P | MASK_UFRAME0,bedesc);
|
328 |
|
|
qho->curr = cond_bswap((int)qtdo,bedesc);
|
329 |
|
|
qho->qtd.next = cond_bswap(EHC_T,bedesc);
|
330 |
|
|
qho->qtd.anext = cond_bswap(EHC_T,bedesc);
|
331 |
|
|
qho->qtd.token = cond_bswap((1 << qTD_TOTALB_P) |
|
332 |
|
|
(qTD_OUT << qTD_PID_P) | qTD_ACTIVE,bedesc);
|
333 |
|
|
qho->qtd.bufp[0] = cond_bswap((int)buf | 1,bedesc);
|
334 |
|
|
qtdo->next = cond_bswap(EHC_T,bedesc);
|
335 |
|
|
qtdo->anext = cond_bswap(EHC_T,bedesc);
|
336 |
|
|
qtdo->token = cond_bswap((1 << qTD_TOTALB_P) |
|
337 |
|
|
(qTD_OUT << qTD_PID_P) | qTD_ACTIVE,bedesc);
|
338 |
|
|
qtdo->bufp[0] = cond_bswap((int)buf | 1,bedesc);
|
339 |
|
|
|
340 |
|
|
qhi->lp = cond_bswap(EHC_T,bedesc);
|
341 |
|
|
qhi->chr = cond_bswap((1 << QH_MAXP_P) | (EHC_HS << QH_EPS_P) |
|
342 |
|
|
(1 << QH_ENDPT_P),bedesc);
|
343 |
|
|
qhi->cap = cond_bswap(1 << QH_MULT_P | MASK_UFRAME0,bedesc);
|
344 |
|
|
qhi->curr = cond_bswap((int)qtdi,bedesc);
|
345 |
|
|
qhi->qtd.next = cond_bswap(EHC_T,bedesc);
|
346 |
|
|
qhi->qtd.anext = cond_bswap(EHC_T,bedesc);
|
347 |
|
|
qhi->qtd.token = cond_bswap((1 << qTD_TOTALB_P) | qTD_IOC |
|
348 |
|
|
(qTD_IN << qTD_PID_P) | qTD_ACTIVE,bedesc);
|
349 |
|
|
qhi->qtd.bufp[0] = cond_bswap((int)buf | 1,bedesc);
|
350 |
|
|
qtdi->next = cond_bswap(EHC_T,bedesc);
|
351 |
|
|
qtdi->anext = cond_bswap(EHC_T,bedesc);
|
352 |
|
|
qtdi->token = cond_bswap((1 << qTD_TOTALB_P) | qTD_IOC |
|
353 |
|
|
(qTD_IN << qTD_PID_P) | qTD_ACTIVE,bedesc);
|
354 |
|
|
qtdi->bufp[0] = cond_bswap((int)buf | 1,bedesc);
|
355 |
|
|
|
356 |
|
|
flbase[0] = cond_bswap((int)itdo,bedesc);
|
357 |
|
|
|
358 |
|
|
c->perlistbase = cond_bswap((int)flbase,beregs);
|
359 |
|
|
|
360 |
|
|
/* If the processor is operating at a high frequency we may
|
361 |
|
|
set port reset to 0 too fast */
|
362 |
|
|
a->portsc[0] &= cond_bswap(~EHC_PORTSC_PRESET,beregs);
|
363 |
|
|
|
364 |
|
|
while (!(a->portsc[0] & cond_bswap(EHC_PORTSC_PEN,beregs)))
|
365 |
|
|
;
|
366 |
|
|
|
367 |
|
|
c->usbsts = c->usbsts;
|
368 |
|
|
|
369 |
|
|
c->usbcmd = cond_bswap((1 << EHC_USBCMD_ITHRES_P) | EHC_USBCMD_PER_SCHED_EN |
|
370 |
|
|
EHC_USBCMD_RUNSTOP,beregs);
|
371 |
|
|
|
372 |
|
|
/* Build schedule for test 4 */
|
373 |
|
|
aqh = memalign(32, sizeof(struct ehc_qh));
|
374 |
|
|
aqtdi = memalign(32, sizeof(struct ehc_qtd));
|
375 |
|
|
aqtdo = memalign(32, sizeof(struct ehc_qtd));
|
376 |
|
|
|
377 |
|
|
aqh->lp = cond_bswap((int)aqh,bedesc);
|
378 |
|
|
aqh->chr = cond_bswap((1 << QH_MAXP_P) | QH_H | QH_DTC |
|
379 |
|
|
(EHC_HS << QH_EPS_P) | (1 << QH_ENDPT_P),bedesc);
|
380 |
|
|
aqh->cap = cond_bswap(1 << QH_MULT_P,bedesc);
|
381 |
|
|
aqh->curr = cond_bswap((int)aqtdo,bedesc);
|
382 |
|
|
aqh->qtd.next = cond_bswap((int)aqtdi,bedesc);
|
383 |
|
|
aqh->qtd.anext = cond_bswap(EHC_T,bedesc);
|
384 |
|
|
aqh->qtd.token = cond_bswap((1 << qTD_TOTALB_P) | qTD_IOC |
|
385 |
|
|
(qTD_OUT << qTD_PID_P) | qTD_ACTIVE,bedesc);
|
386 |
|
|
aqh->qtd.bufp[0] = cond_bswap((int)buf,bedesc);
|
387 |
|
|
aqtdo->next = cond_bswap((int)aqtdi,bedesc);
|
388 |
|
|
aqtdo->anext = cond_bswap(EHC_T,bedesc);
|
389 |
|
|
aqtdo->token = cond_bswap((1 << qTD_TOTALB_P) | qTD_IOC |
|
390 |
|
|
(qTD_OUT << qTD_PID_P) | qTD_ACTIVE,bedesc);
|
391 |
|
|
aqtdo->bufp[0] = cond_bswap((int)buf,bedesc);
|
392 |
|
|
|
393 |
|
|
aqtdi->next = cond_bswap(EHC_T,bedesc);
|
394 |
|
|
aqtdi->anext = cond_bswap(EHC_T,bedesc);
|
395 |
|
|
aqtdi->token = cond_bswap((qTD_IN << qTD_PID_P) | qTD_ACTIVE,bedesc);
|
396 |
|
|
aqtdi->bufp[0] = cond_bswap((int)buf,bedesc);
|
397 |
|
|
|
398 |
|
|
|
399 |
|
|
while (!(c->usbsts & cond_bswap(EHC_USBSTS_USBINT,beregs)))
|
400 |
|
|
;
|
401 |
|
|
|
402 |
|
|
if (c->usbsts != cond_bswap(EHC_USBSTS_PERSTAT |
|
403 |
|
|
EHC_USBSTS_USBINT, beregs))
|
404 |
|
|
fail(2);
|
405 |
|
|
|
406 |
|
|
if (itdo->lp != cond_bswap((int)itdi,bedesc))
|
407 |
|
|
fail(3);
|
408 |
|
|
if (itdo->status[0] != cond_bswap((1 << iTD_TLEN_P) | 1,bedesc))
|
409 |
|
|
fail(4);
|
410 |
|
|
if (itdo->buf[0] != cond_bswap((int)buf,bedesc))
|
411 |
|
|
fail(5);
|
412 |
|
|
if (itdo->buf[1] != cond_bswap(1,bedesc))
|
413 |
|
|
fail(6);
|
414 |
|
|
if (itdo->buf[2] != cond_bswap(1,bedesc))
|
415 |
|
|
fail(7);
|
416 |
|
|
if (itdi->lp != cond_bswap((int)qho | EHC_TYP_QH ,bedesc))
|
417 |
|
|
fail(8);
|
418 |
|
|
if (itdi->status[0] != cond_bswap((1 << iTD_TLEN_P) | 1,bedesc))
|
419 |
|
|
fail(9);
|
420 |
|
|
if (itdi->buf[0] != cond_bswap((int)buf,bedesc))
|
421 |
|
|
fail(10);
|
422 |
|
|
if (itdi->buf[1] != cond_bswap(iTD_IO | 1,bedesc))
|
423 |
|
|
fail(11);
|
424 |
|
|
if (itdi->buf[2] != cond_bswap(1,bedesc))
|
425 |
|
|
fail(12);
|
426 |
|
|
|
427 |
|
|
if (*buf != 0x55)
|
428 |
|
|
fail(13);
|
429 |
|
|
|
430 |
|
|
if (qho->lp != cond_bswap((int)qhi | EHC_TYP_QH,bedesc))
|
431 |
|
|
fail(14);
|
432 |
|
|
if (qho->chr != cond_bswap((1 << QH_MAXP_P) | (EHC_HS << QH_EPS_P) |
|
433 |
|
|
(1 << QH_ENDPT_P),bedesc))
|
434 |
|
|
fail(15);
|
435 |
|
|
if (qho->cap != cond_bswap(1 << QH_MULT_P | MASK_UFRAME0,bedesc))
|
436 |
|
|
fail(16);
|
437 |
|
|
if (qho->curr != cond_bswap((int)qtdo,bedesc))
|
438 |
|
|
fail(17);
|
439 |
|
|
if (qho->qtd.next != cond_bswap(EHC_T,bedesc))
|
440 |
|
|
fail(18);
|
441 |
|
|
if (qho->qtd.anext != cond_bswap(EHC_T,bedesc))
|
442 |
|
|
fail(19);
|
443 |
|
|
if (qho->qtd.token != cond_bswap(qTD_DT | (qTD_OUT << qTD_PID_P),bedesc))
|
444 |
|
|
fail(20);
|
445 |
|
|
if (qho->qtd.bufp[0] != cond_bswap((int)buf | 2,bedesc))
|
446 |
|
|
fail(21);
|
447 |
|
|
if (qtdo->next != cond_bswap(EHC_T,bedesc))
|
448 |
|
|
fail(22);
|
449 |
|
|
if (qtdo->anext != cond_bswap(EHC_T,bedesc))
|
450 |
|
|
fail(23);
|
451 |
|
|
if (qtdo->token != cond_bswap(qTD_DT | (qTD_OUT << qTD_PID_P),bedesc))
|
452 |
|
|
fail(24);
|
453 |
|
|
if (qtdo->bufp[0] != cond_bswap((int)buf | 1,bedesc))
|
454 |
|
|
fail(25);
|
455 |
|
|
|
456 |
|
|
if (qhi->lp != cond_bswap(EHC_T,bedesc))
|
457 |
|
|
fail(26);
|
458 |
|
|
if (qhi->chr != cond_bswap((1 << QH_MAXP_P) | (EHC_HS << QH_EPS_P) |
|
459 |
|
|
(1 << QH_ENDPT_P),bedesc))
|
460 |
|
|
fail(27);
|
461 |
|
|
if (qhi->cap != cond_bswap(1 << QH_MULT_P | MASK_UFRAME0,bedesc))
|
462 |
|
|
fail(28);
|
463 |
|
|
if (qhi->curr != cond_bswap((int)qtdi,bedesc))
|
464 |
|
|
fail(29);
|
465 |
|
|
if (qhi->qtd.next != cond_bswap(EHC_T,bedesc))
|
466 |
|
|
fail(30);
|
467 |
|
|
if (qhi->qtd.anext != cond_bswap(EHC_T,bedesc))
|
468 |
|
|
fail(31);
|
469 |
|
|
if (qhi->qtd.token != cond_bswap(qTD_DT | qTD_IOC |
|
470 |
|
|
(qTD_IN << qTD_PID_P),bedesc))
|
471 |
|
|
fail(32);
|
472 |
|
|
if (qhi->qtd.bufp[0] != cond_bswap((int)buf | 2,bedesc))
|
473 |
|
|
fail(33);
|
474 |
|
|
if (qtdi->next != cond_bswap(EHC_T,bedesc))
|
475 |
|
|
fail(34);
|
476 |
|
|
if (qtdi->anext != cond_bswap(EHC_T,bedesc))
|
477 |
|
|
fail(35);
|
478 |
|
|
if (qtdi->token != cond_bswap(qTD_DT | qTD_IOC |
|
479 |
|
|
(qTD_IN << qTD_PID_P),bedesc))
|
480 |
|
|
fail(36);
|
481 |
|
|
if (qtdi->bufp[0] != cond_bswap((int)buf | 1,bedesc))
|
482 |
|
|
fail(37);
|
483 |
|
|
|
484 |
|
|
if (*(buf+1) != 0x44)
|
485 |
|
|
fail(38);
|
486 |
|
|
|
487 |
|
|
c->usbsts = c->usbsts;
|
488 |
|
|
|
489 |
|
|
/* Transfer 1b SETUP OUT and 0b bulk IN which should lead to babble error,
|
490 |
|
|
first traverse inactive per. sched. */
|
491 |
|
|
report_subtest(4);
|
492 |
|
|
|
493 |
|
|
c->alistaddr = cond_bswap((int)aqh,beregs);
|
494 |
|
|
|
495 |
|
|
/* Enable both schedules */
|
496 |
|
|
c->usbcmd = cond_bswap((1 << EHC_USBCMD_ITHRES_P) | EHC_USBCMD_PER_SCHED_EN |
|
497 |
|
|
EHC_USBCMD_AS_SCHED_EN | EHC_USBCMD_RUNSTOP,beregs);
|
498 |
|
|
|
499 |
|
|
while (!(c->usbsts & cond_bswap(EHC_USBSTS_USBERRINT,beregs)))
|
500 |
|
|
;
|
501 |
|
|
|
502 |
|
|
if (c->usbsts != cond_bswap(EHC_USBSTS_PERSTAT | EHC_USBSTS_ASSTAT |
|
503 |
|
|
EHC_USBSTS_USBERRINT | EHC_USBSTS_USBINT, beregs))
|
504 |
|
|
fail(1);
|
505 |
|
|
|
506 |
|
|
c->usbcmd = 0;
|
507 |
|
|
|
508 |
|
|
if (aqh->lp != cond_bswap((int)aqh,bedesc))
|
509 |
|
|
fail(2);
|
510 |
|
|
if (aqh->chr != cond_bswap((1 << QH_MAXP_P) | QH_H | QH_DTC |
|
511 |
|
|
(EHC_HS << QH_EPS_P) | (1 << QH_ENDPT_P),bedesc))
|
512 |
|
|
fail(3);
|
513 |
|
|
if (aqh->cap != cond_bswap(1 << QH_MULT_P,bedesc))
|
514 |
|
|
fail(4);
|
515 |
|
|
if (aqh->curr != cond_bswap((int)aqtdi,bedesc))
|
516 |
|
|
fail(5);
|
517 |
|
|
if (aqh->qtd.next != cond_bswap(EHC_T,bedesc))
|
518 |
|
|
fail(6);
|
519 |
|
|
if (aqh->qtd.anext != cond_bswap(EHC_T,bedesc))
|
520 |
|
|
fail(7);
|
521 |
|
|
if (aqh->qtd.token != cond_bswap((qTD_IN << qTD_PID_P) | qTD_HALTBABXACT,bedesc))
|
522 |
|
|
fail(8);
|
523 |
|
|
if (aqh->qtd.bufp[0] != cond_bswap((int)buf,bedesc))
|
524 |
|
|
fail(9);
|
525 |
|
|
if (aqtdo->next != cond_bswap((int)aqtdi,bedesc))
|
526 |
|
|
fail(10);
|
527 |
|
|
if (aqtdo->anext != cond_bswap(EHC_T,bedesc))
|
528 |
|
|
fail(11);
|
529 |
|
|
if (aqtdo->token != cond_bswap(qTD_DT | qTD_IOC | qTD_OUT << qTD_PID_P,bedesc))
|
530 |
|
|
fail(12);
|
531 |
|
|
if (aqtdo->bufp[0] != cond_bswap((int)buf,bedesc))
|
532 |
|
|
fail(13);
|
533 |
|
|
if (aqtdi->next != cond_bswap(EHC_T,bedesc))
|
534 |
|
|
fail(14);
|
535 |
|
|
if (aqtdi->anext != cond_bswap(EHC_T,bedesc))
|
536 |
|
|
fail(15);
|
537 |
|
|
if (aqtdi->token != cond_bswap((qTD_IN << qTD_PID_P) | qTD_HALTBABXACT,bedesc))
|
538 |
|
|
fail(16);
|
539 |
|
|
if (aqtdi->bufp[0] != cond_bswap((int)buf,bedesc))
|
540 |
|
|
fail(17);
|
541 |
|
|
|
542 |
|
|
free(itdi);
|
543 |
|
|
free(itdo);
|
544 |
|
|
free(qhi);
|
545 |
|
|
free(qho);
|
546 |
|
|
free(qtdi);
|
547 |
|
|
free(qtdo);
|
548 |
|
|
free(aqh);
|
549 |
|
|
free(aqtdi);
|
550 |
|
|
free(aqtdo);
|
551 |
|
|
free(buf);
|
552 |
|
|
free(flbase);
|
553 |
|
|
|
554 |
|
|
while (!(c->usbsts & cond_bswap(EHC_USBSTS_HCHALTED,beregs)))
|
555 |
|
|
;
|
556 |
|
|
|
557 |
|
|
a->configflag = 0;
|
558 |
|
|
|
559 |
|
|
return 0;
|
560 |
|
|
}
|
561 |
|
|
|
562 |
|
|
/*********************/
|
563 |
|
|
/* UHC specific code */
|
564 |
|
|
/*********************/
|
565 |
|
|
|
566 |
|
|
/* Register fields */
|
567 |
|
|
/* USBCMD */
|
568 |
|
|
#define UHC_USBCMD_UMAXP (1 << 7)
|
569 |
|
|
#define UHC_USBCMD_UCF (1 << 6)
|
570 |
|
|
#define UHC_USBCMD_SWDBG (1 << 5)
|
571 |
|
|
#define UHC_USBCMD_FGR (1 << 4)
|
572 |
|
|
#define UHC_USBCMD_EGSM (1 << 3)
|
573 |
|
|
#define UHC_USBCMD_GRESET (1 << 2)
|
574 |
|
|
#define UHC_USBCMD_HCRESET (1 << 1)
|
575 |
|
|
#define UHC_USBCMD_RUNSTOP (1 << 0)
|
576 |
|
|
|
577 |
|
|
/* USBSTS */
|
578 |
|
|
#define UHC_USBSTS_HCHALTED (1 << 5)
|
579 |
|
|
#define UHC_USBSTS_HCP (1 << 4)
|
580 |
|
|
#define UHC_USBSTS_HCERROR (1 << 3)
|
581 |
|
|
#define UHC_USBSTS_RSDETECT (1 << 2)
|
582 |
|
|
#define UHC_USBSTS_USBERRINT (1 << 1)
|
583 |
|
|
#define UHC_USBSTS_USBINT (1 << 0)
|
584 |
|
|
|
585 |
|
|
/* PORTSC */
|
586 |
|
|
#define UHC_PORTSC_SUSPEND (1 << 12)
|
587 |
|
|
#define UHC_PORTSC_PRESET (1 << 9)
|
588 |
|
|
#define UHC_PORTSC_LS (1 << 8)
|
589 |
|
|
#define UHC_PORTSC_RES (1 << 7)
|
590 |
|
|
#define UHC_PORTSC_RSDETECT (1 << 6)
|
591 |
|
|
#define UHC_PORTSC_LINESTATUS (3 << 4)
|
592 |
|
|
#define UHC_PORTSC_PEN_CHANGE (1 << 3)
|
593 |
|
|
#define UHC_PORTSC_PEN (1 << 2)
|
594 |
|
|
#define UHC_PORTSC_CNNTSTATC (1 << 1)
|
595 |
|
|
#define UHC_PORTSC_CNNTSTAT (1 << 0)
|
596 |
|
|
|
597 |
|
|
/* Reset values */
|
598 |
|
|
#define UHC_USBCMD_RESVAL 0x0000
|
599 |
|
|
#define UHC_USBSTS_RESVAL 0x0020
|
600 |
|
|
#define UHC_USBINT_RESVAL 0x0000
|
601 |
|
|
#define UHC_FRNUM_RESVAL 0x0000
|
602 |
|
|
#define UHC_SOFMOD_RESVAL(b) (b ? 0x4000 : 0x40)
|
603 |
|
|
#define UHC_PORTSC_RESVAL 0x0083
|
604 |
|
|
|
605 |
|
|
struct uhcregs {
|
606 |
|
|
volatile unsigned int usbcmdsts;
|
607 |
|
|
volatile unsigned int usbintfrnum;
|
608 |
|
|
volatile unsigned int fladdr;
|
609 |
|
|
volatile unsigned int sofmod;
|
610 |
|
|
volatile unsigned int portsc[4];
|
611 |
|
|
};
|
612 |
|
|
|
613 |
|
|
|
614 |
|
|
/* TD fields and helper defines */
|
615 |
|
|
#define TD_VF (1 << 2)
|
616 |
|
|
#define TD_Q (1 << 1)
|
617 |
|
|
#define TD_T (1 << 0)
|
618 |
|
|
|
619 |
|
|
#define TD_SPD (1 << 29)
|
620 |
|
|
#define TD_CERR_P 27
|
621 |
|
|
#define TD_LS (1 << 26)
|
622 |
|
|
#define TD_ISO (1 << 25)
|
623 |
|
|
#define TD_IOC (1 << 24)
|
624 |
|
|
#define TD_STATUS (255 << 16)
|
625 |
|
|
#define TD_STATUS_P 16
|
626 |
|
|
#define TD_STATUS_ACTIVE 0x80
|
627 |
|
|
#define TD_ACTIVE (TD_STATUS_ACTIVE << TD_STATUS_P)
|
628 |
|
|
#define TD_MAXLEN_P 21
|
629 |
|
|
#define TD_ENDPT_P 15
|
630 |
|
|
#define TD_D (1 << 19)
|
631 |
|
|
|
632 |
|
|
|
633 |
|
|
/* PIDS */
|
634 |
|
|
#define TD_PID_IN 0x69
|
635 |
|
|
#define TD_PID_OUT 0xE1
|
636 |
|
|
#define TD_PID_SETUP 0x2D
|
637 |
|
|
|
638 |
|
|
struct uhc_td {
|
639 |
|
|
volatile unsigned int lp;
|
640 |
|
|
volatile unsigned int stat;
|
641 |
|
|
volatile unsigned int token;
|
642 |
|
|
volatile unsigned int bufp;
|
643 |
|
|
};
|
644 |
|
|
|
645 |
|
|
struct uhc_qh {
|
646 |
|
|
volatile unsigned int lp;
|
647 |
|
|
volatile unsigned int elp;
|
648 |
|
|
volatile unsigned int pad1;
|
649 |
|
|
volatile unsigned int pad2;
|
650 |
|
|
};
|
651 |
|
|
|
652 |
|
|
|
653 |
|
|
#define get_lhw(x) ((x >> 16) & 0xffff)
|
654 |
|
|
#define get_hhw(x) (x & 0xffff)
|
655 |
|
|
|
656 |
|
|
#define fix_end(x) (beregs ? x : hword_swap(byte_swap(x)))
|
657 |
|
|
|
658 |
|
|
#define cond_regswap(x) (beregs ? x : byte_swap(hword_swap(x)))
|
659 |
|
|
|
660 |
|
|
#define get_usbcmd(x) get_lhw(fix_end(x->usbcmdsts))
|
661 |
|
|
#define get_usbsts(x) get_hhw(fix_end(x->usbcmdsts))
|
662 |
|
|
#define get_usbint(x) get_lhw(fix_end(x->usbintfrnum))
|
663 |
|
|
#define get_frnum(x) get_hhw(fix_end(x->usbintfrnum))
|
664 |
|
|
#define get_fladdr(x) byte_swap(x->fladdr)
|
665 |
|
|
#define get_sofmod(x) get_lhw(fix_end(x->sofmod))
|
666 |
|
|
#define get_portsc(x, i) (i % 2 ? get_hhw(fix_end(x->portsc[i/2])) : get_lhw(fix_end(x->portsc[i/2])))
|
667 |
|
|
|
668 |
|
|
void uhc_check_resvals(struct uhcregs *regs, int beregs)
|
669 |
|
|
{
|
670 |
|
|
int i = 0;
|
671 |
|
|
|
672 |
|
|
if (get_usbcmd(regs) != UHC_USBCMD_RESVAL)
|
673 |
|
|
fail(0);
|
674 |
|
|
if (get_usbsts(regs) != UHC_USBSTS_RESVAL)
|
675 |
|
|
fail(1);
|
676 |
|
|
if (get_usbint(regs) != UHC_USBINT_RESVAL)
|
677 |
|
|
fail(2);
|
678 |
|
|
if (get_frnum(regs) != UHC_FRNUM_RESVAL)
|
679 |
|
|
fail(3);
|
680 |
|
|
/* fladdr has undefined reset value */
|
681 |
|
|
if (get_sofmod(regs) != UHC_SOFMOD_RESVAL(beregs))
|
682 |
|
|
fail(4);
|
683 |
|
|
while (get_portsc(regs,i) & UHC_PORTSC_RES) {
|
684 |
|
|
if (get_portsc(regs,i) != UHC_PORTSC_RESVAL)
|
685 |
|
|
fail(5+i);
|
686 |
|
|
i++;
|
687 |
|
|
}
|
688 |
|
|
}
|
689 |
|
|
|
690 |
|
|
|
691 |
|
|
int uhc_test(int addr, int bedesc, int beregs)
|
692 |
|
|
{
|
693 |
|
|
int i;
|
694 |
|
|
|
695 |
|
|
struct uhc_td *td;
|
696 |
|
|
struct uhc_qh *qh;
|
697 |
|
|
char *buf;
|
698 |
|
|
int *flbase;
|
699 |
|
|
struct uhcregs *regs;
|
700 |
|
|
|
701 |
|
|
report_device(0x01027000);
|
702 |
|
|
|
703 |
|
|
regs = (struct uhcregs*)addr;
|
704 |
|
|
|
705 |
|
|
/* Check register reset values */
|
706 |
|
|
report_subtest(1);
|
707 |
|
|
|
708 |
|
|
uhc_check_resvals(regs, beregs);
|
709 |
|
|
|
710 |
|
|
/* Perform HC reset */
|
711 |
|
|
report_subtest(2);
|
712 |
|
|
|
713 |
|
|
regs->usbcmdsts = cond_regswap(UHC_USBCMD_HCRESET);
|
714 |
|
|
|
715 |
|
|
while (get_usbcmd(regs) & UHC_USBCMD_HCRESET)
|
716 |
|
|
;
|
717 |
|
|
|
718 |
|
|
uhc_check_resvals(regs, beregs);
|
719 |
|
|
|
720 |
|
|
/* Transfer 1 byte isoch packet OUT and IN */
|
721 |
|
|
report_subtest(3);
|
722 |
|
|
|
723 |
|
|
flbase = build_frame_list(2, bedesc);
|
724 |
|
|
|
725 |
|
|
buf = malloc(1);
|
726 |
|
|
td = memalign(16, 2*sizeof(struct uhc_td));
|
727 |
|
|
|
728 |
|
|
*buf = 0xaa;
|
729 |
|
|
|
730 |
|
|
td[0].lp = cond_bswap((int)(td+1), bedesc);
|
731 |
|
|
td[0].stat = cond_bswap(TD_ISO | TD_ACTIVE, bedesc);
|
732 |
|
|
td[0].token = cond_bswap(TD_PID_OUT, bedesc);
|
733 |
|
|
td[0].bufp = cond_bswap((int)buf, bedesc);
|
734 |
|
|
|
735 |
|
|
td[1].lp = cond_bswap(TD_T, bedesc);
|
736 |
|
|
td[1].stat = cond_bswap(TD_ISO | TD_IOC | TD_ACTIVE, bedesc);
|
737 |
|
|
td[1].token = cond_bswap(TD_PID_IN, bedesc);
|
738 |
|
|
td[1].bufp = cond_bswap((int)buf, bedesc);
|
739 |
|
|
|
740 |
|
|
flbase[0] = cond_bswap((int)td, bedesc);
|
741 |
|
|
|
742 |
|
|
regs->fladdr = cond_bswap((int)flbase, beregs);
|
743 |
|
|
|
744 |
|
|
regs->portsc[0] = cond_regswap(UHC_PORTSC_PEN << 16);
|
745 |
|
|
|
746 |
|
|
regs->usbcmdsts = cond_regswap(UHC_USBCMD_RUNSTOP << 16);
|
747 |
|
|
|
748 |
|
|
while (!get_usbsts(regs))
|
749 |
|
|
;
|
750 |
|
|
|
751 |
|
|
if (!(get_usbsts(regs) & UHC_USBSTS_USBINT) || (get_usbsts(regs) >> 1))
|
752 |
|
|
fail(0);
|
753 |
|
|
|
754 |
|
|
regs->usbcmdsts = cond_regswap(0x0000ffff);
|
755 |
|
|
|
756 |
|
|
if (!(get_usbsts(regs) & UHC_USBSTS_HCHALTED))
|
757 |
|
|
fail(1);
|
758 |
|
|
|
759 |
|
|
|
760 |
|
|
if (td[0].lp != cond_bswap((int)(td+1),bedesc))
|
761 |
|
|
fail(2);
|
762 |
|
|
if (td[0].stat != cond_bswap(TD_ISO,bedesc))
|
763 |
|
|
fail(3);
|
764 |
|
|
if (td[0].token != cond_bswap(TD_PID_OUT,bedesc))
|
765 |
|
|
fail(4);
|
766 |
|
|
if (td[0].bufp != cond_bswap((int)buf,bedesc))
|
767 |
|
|
fail(5);
|
768 |
|
|
if (td[1].lp != cond_bswap(TD_T,bedesc))
|
769 |
|
|
fail(6);
|
770 |
|
|
if (td[1].stat != cond_bswap(TD_ISO | TD_IOC,bedesc))
|
771 |
|
|
fail(7);
|
772 |
|
|
if (td[1].token != cond_bswap(TD_PID_IN,bedesc))
|
773 |
|
|
fail(8);
|
774 |
|
|
if (td[1].bufp != cond_bswap((int)buf,bedesc))
|
775 |
|
|
fail(9);
|
776 |
|
|
if (*buf != 0x55)
|
777 |
|
|
fail(10);
|
778 |
|
|
|
779 |
|
|
/* Transfer 0 byte control OUT and bulk IN */
|
780 |
|
|
report_subtest(4);
|
781 |
|
|
|
782 |
|
|
qh = memalign(16, 2*sizeof(struct uhc_qh));
|
783 |
|
|
|
784 |
|
|
qh[0].lp = cond_bswap((int)(qh+1) | TD_Q,bedesc);
|
785 |
|
|
qh[0].elp = cond_bswap((int)td,bedesc);
|
786 |
|
|
|
787 |
|
|
qh[1].lp = cond_bswap(TD_T,bedesc);
|
788 |
|
|
qh[1].elp = cond_bswap((int)(td+1),bedesc);
|
789 |
|
|
|
790 |
|
|
td[0].lp = cond_bswap(TD_T,bedesc);
|
791 |
|
|
td[0].stat = cond_bswap(TD_ACTIVE,bedesc);
|
792 |
|
|
td[0].token = cond_bswap((0x7FF << TD_MAXLEN_P) | (1 << TD_ENDPT_P) |
|
793 |
|
|
TD_PID_SETUP,bedesc);
|
794 |
|
|
td[0].bufp = cond_bswap((int)buf,bedesc);
|
795 |
|
|
|
796 |
|
|
td[1].lp = cond_bswap(TD_T,bedesc);
|
797 |
|
|
td[1].stat = cond_bswap(TD_IOC | TD_ACTIVE,bedesc);
|
798 |
|
|
td[1].token = cond_bswap((0x7FF << TD_MAXLEN_P) | (1 << TD_ENDPT_P) |
|
799 |
|
|
TD_PID_IN,bedesc);
|
800 |
|
|
td[1].bufp = cond_bswap((int)buf,bedesc);
|
801 |
|
|
|
802 |
|
|
flbase[0] = cond_bswap((int)qh | TD_Q,bedesc);
|
803 |
|
|
|
804 |
|
|
regs->usbcmdsts = cond_regswap(UHC_USBCMD_RUNSTOP << 16);
|
805 |
|
|
|
806 |
|
|
while (!get_usbsts(regs))
|
807 |
|
|
;
|
808 |
|
|
|
809 |
|
|
if (!(get_usbsts(regs) & UHC_USBSTS_USBINT) || (get_usbsts(regs) >> 1))
|
810 |
|
|
fail(0);
|
811 |
|
|
|
812 |
|
|
regs->usbcmdsts = cond_regswap(0x0000ffff);
|
813 |
|
|
|
814 |
|
|
if (!(get_usbsts(regs) & UHC_USBSTS_HCHALTED))
|
815 |
|
|
fail(1);
|
816 |
|
|
|
817 |
|
|
if (td[0].lp != cond_bswap(TD_T,bedesc))
|
818 |
|
|
fail(2);
|
819 |
|
|
if (td[0].stat != cond_bswap(0x7ff,bedesc))
|
820 |
|
|
fail(3);
|
821 |
|
|
if (td[0].token != cond_bswap((0x7FF << TD_MAXLEN_P) | (1 << TD_ENDPT_P) |
|
822 |
|
|
TD_PID_SETUP,bedesc))
|
823 |
|
|
fail(4);
|
824 |
|
|
if (td[0].bufp != cond_bswap((int)buf,bedesc))
|
825 |
|
|
fail(5);
|
826 |
|
|
if (td[1].lp != cond_bswap(TD_T,bedesc))
|
827 |
|
|
fail(6);
|
828 |
|
|
if (td[1].stat != cond_bswap(TD_IOC | 0x7ff,bedesc))
|
829 |
|
|
fail(7);
|
830 |
|
|
if (td[1].token != cond_bswap((0x7FF << TD_MAXLEN_P) | (1 << TD_ENDPT_P) |
|
831 |
|
|
TD_PID_IN,bedesc))
|
832 |
|
|
fail(8);
|
833 |
|
|
if (td[1].bufp != cond_bswap((int)buf,bedesc))
|
834 |
|
|
fail(9);
|
835 |
|
|
if (*buf != 0x55)
|
836 |
|
|
fail(10);
|
837 |
|
|
|
838 |
|
|
if (qh[0].lp != cond_bswap((int)(qh+1) | TD_Q,bedesc))
|
839 |
|
|
fail(11);
|
840 |
|
|
if (qh[0].elp != cond_bswap(TD_T,bedesc))
|
841 |
|
|
fail(12);
|
842 |
|
|
if (qh[1].lp != cond_bswap(TD_T,bedesc))
|
843 |
|
|
fail(13);
|
844 |
|
|
if (qh[1].elp != cond_bswap(TD_T,bedesc))
|
845 |
|
|
fail(14);
|
846 |
|
|
|
847 |
|
|
free(td);
|
848 |
|
|
free(qh);
|
849 |
|
|
free(buf);
|
850 |
|
|
free(flbase);
|
851 |
|
|
|
852 |
|
|
return 0;
|
853 |
|
|
}
|
854 |
|
|
|
855 |
|
|
/*****************/
|
856 |
|
|
/* Complete test */
|
857 |
|
|
/*****************/
|
858 |
|
|
|
859 |
|
|
int grusbhc_test(int ehc_addr, int uhc_addr, int bedesc, int beregs)
|
860 |
|
|
{
|
861 |
|
|
if (uhc_addr)
|
862 |
|
|
uhc_test(uhc_addr, bedesc, beregs);
|
863 |
|
|
|
864 |
|
|
if (ehc_addr)
|
865 |
|
|
ehc_test(ehc_addr, bedesc, beregs);
|
866 |
|
|
|
867 |
|
|
return 0;
|
868 |
|
|
}
|