packages: clean up the package folder
[openwrt.git] / package / kernel / lantiq / ltq-hcd / src / ifxhcd_es.c
1 /*****************************************************************************
2  **   FILE NAME       : ifxhcd_es.c
3  **   PROJECT         : IFX USB sub-system V3
4  **   MODULES         : IFX USB sub-system Host and Device driver
5  **   SRC VERSION     : 1.0
6  **   DATE            : 1/Jan/2009
7  **   AUTHOR          : Chen, Howard
8  **   DESCRIPTION     : The file contain function to enable host mode USB-IF Electrical Test function.
9  **   FUNCTIONS       :
10  **   COMPILER        : gcc
11  **   REFERENCE       : Synopsys DWC-OTG Driver 2.7
12  **   COPYRIGHT       :  Copyright (c) 2010
13  **                      LANTIQ DEUTSCHLAND GMBH,
14  **                      Am Campeon 3, 85579 Neubiberg, Germany
15  **
16  **    This program is free software; you can redistribute it and/or modify
17  **    it under the terms of the GNU General Public License as published by
18  **    the Free Software Foundation; either version 2 of the License, or
19  **    (at your option) any later version.
20  **
21  **  Version Control Section  **
22  **   $Author$
23  **   $Date$
24  **   $Revisions$
25  **   $Log$       Revision history
26  *****************************************************************************/
27
28 /*
29  * This file contains code fragments from Synopsys HS OTG Linux Software Driver.
30  * For this code the following notice is applicable:
31  *
32  * ==========================================================================
33  *
34  * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
35  * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
36  * otherwise expressly agreed to in writing between Synopsys and you.
37  *
38  * The Software IS NOT an item of Licensed Software or Licensed Product under
39  * any End User Software License Agreement or Agreement for Licensed Product
40  * with Synopsys or any supplement thereto. You are permitted to use and
41  * redistribute this Software in source and binary forms, with or without
42  * modification, provided that redistributions of source code must retain this
43  * notice. You may not view, use, disclose, copy or distribute this file or
44  * any information contained herein except pursuant to this license grant from
45  * Synopsys. If you do not agree with this notice, including the disclaimer
46  * below, then you are not authorized to use the Software.
47  *
48  * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
49  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51  * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
52  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
53  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
54  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
55  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
58  * DAMAGE.
59  * ========================================================================== */
60
61 /*!
62  \file ifxhcd_es.c
63  \ingroup IFXUSB_DRIVER_V3
64  \brief The file contain function to enable host mode USB-IF Electrical Test function.
65 */
66
67 #include <linux/version.h>
68 #include "ifxusb_version.h"
69
70 #include <linux/kernel.h>
71
72 #include <linux/errno.h>
73
74 #include <linux/dma-mapping.h>
75
76 #include "ifxusb_plat.h"
77 #include "ifxusb_regs.h"
78 #include "ifxusb_cif.h"
79 #include "ifxhcd.h"
80
81
82 #ifdef __WITH_HS_ELECT_TST__
83         /*
84          * Quick and dirty hack to implement the HS Electrical Test
85          * SINGLE_STEP_GET_DEVICE_DESCRIPTOR feature.
86          *
87          * This code was copied from our userspace app "hset". It sends a
88          * Get Device Descriptor control sequence in two parts, first the
89          * Setup packet by itself, followed some time later by the In and
90          * Ack packets. Rather than trying to figure out how to add this
91          * functionality to the normal driver code, we just hijack the
92          * hardware, using these two function to drive the hardware
93          * directly.
94          */
95
96
97         void do_setup(ifxusb_core_if_t *_core_if)
98         {
99
100                 ifxusb_core_global_regs_t *global_regs    = _core_if->core_global_regs;
101                 ifxusb_host_global_regs_t *hc_global_regs = _core_if->host_global_regs;
102                 ifxusb_hc_regs_t          *hc_regs        = _core_if->hc_regs[0];
103                 uint32_t                  *data_fifo      = _core_if->data_fifo[0];
104
105                 gint_data_t    gintsts;
106                 hctsiz_data_t  hctsiz;
107                 hcchar_data_t  hcchar;
108                 haint_data_t   haint;
109                 hcint_data_t   hcint;
110
111
112                 /* Enable HAINTs */
113                 ifxusb_wreg(&hc_global_regs->haintmsk, 0x0001);
114
115                 /* Enable HCINTs */
116                 ifxusb_wreg(&hc_regs->hcintmsk, 0x04a3);
117
118                 /* Read GINTSTS */
119                 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
120                 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
121
122                 /* Read HAINT */
123                 haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
124                 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
125
126                 /* Read HCINT */
127                 hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
128                 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
129
130                 /* Read HCCHAR */
131                 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
132                 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
133
134                 /* Clear HCINT */
135                 ifxusb_wreg(&hc_regs->hcint, hcint.d32);
136
137                 /* Clear HAINT */
138                 ifxusb_wreg(&hc_global_regs->haint, haint.d32);
139
140                 /* Clear GINTSTS */
141                 ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
142
143                 /* Read GINTSTS */
144                 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
145                 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
146
147                 /*
148                  * Send Setup packet (Get Device Descriptor)
149                  */
150
151                 /* Make sure channel is disabled */
152                 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
153                 if (hcchar.b.chen) {
154                         //fprintf(stderr, "Channel already enabled 1, HCCHAR = %08x\n", hcchar.d32);
155                         hcchar.b.chdis = 1;
156         //              hcchar.b.chen = 1;
157                         ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
158                         //sleep(1);
159                         mdelay(1000);
160
161                         /* Read GINTSTS */
162                         gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
163                         //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
164
165                         /* Read HAINT */
166                         haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
167                         //fprintf(stderr, "HAINT: %08x\n", haint.d32);
168
169                         /* Read HCINT */
170                         hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
171                         //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
172
173                         /* Read HCCHAR */
174                         hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
175                         //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
176
177                         /* Clear HCINT */
178                         ifxusb_wreg(&hc_regs->hcint, hcint.d32);
179
180                         /* Clear HAINT */
181                         ifxusb_wreg(&hc_global_regs->haint, haint.d32);
182
183                         /* Clear GINTSTS */
184                         ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
185
186                         hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
187                         //if (hcchar.b.chen) {
188                         //      fprintf(stderr, "** Channel _still_ enabled 1, HCCHAR = %08x **\n", hcchar.d32);
189                         //}
190                 }
191
192                 /* Set HCTSIZ */
193                 hctsiz.d32 = 0;
194                 hctsiz.b.xfersize = 8;
195                 hctsiz.b.pktcnt = 1;
196                 hctsiz.b.pid = IFXUSB_HC_PID_SETUP;
197                 ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
198
199                 /* Set HCCHAR */
200                 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
201                 hcchar.b.eptype = IFXUSB_EP_TYPE_CTRL;
202                 hcchar.b.epdir = 0;
203                 hcchar.b.epnum = 0;
204                 hcchar.b.mps = 8;
205                 hcchar.b.chen = 1;
206                 ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
207
208                 /* Fill FIFO with Setup data for Get Device Descriptor */
209                 ifxusb_wreg(data_fifo++, 0x01000680);
210                 ifxusb_wreg(data_fifo++, 0x00080000);
211
212                 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
213                 //fprintf(stderr, "Waiting for HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
214
215                 /* Wait for host channel interrupt */
216                 do {
217                         gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
218                 } while (gintsts.b.hcintr == 0);
219
220                 //fprintf(stderr, "Got HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
221
222                 /* Disable HCINTs */
223                 ifxusb_wreg(&hc_regs->hcintmsk, 0x0000);
224
225                 /* Disable HAINTs */
226                 ifxusb_wreg(&hc_global_regs->haintmsk, 0x0000);
227
228                 /* Read HAINT */
229                 haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
230                 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
231
232                 /* Read HCINT */
233                 hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
234                 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
235
236                 /* Read HCCHAR */
237                 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
238                 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
239
240                 /* Clear HCINT */
241                 ifxusb_wreg(&hc_regs->hcint, hcint.d32);
242
243                 /* Clear HAINT */
244                 ifxusb_wreg(&hc_global_regs->haint, haint.d32);
245
246                 /* Clear GINTSTS */
247                 ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
248
249                 /* Read GINTSTS */
250                 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
251                 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
252         }
253
254         void do_in_ack(ifxusb_core_if_t *_core_if)
255         {
256
257                 ifxusb_core_global_regs_t *global_regs    = _core_if->core_global_regs;
258                 ifxusb_host_global_regs_t *hc_global_regs = _core_if->host_global_regs;
259                 ifxusb_hc_regs_t          *hc_regs        = _core_if->hc_regs[0];
260                 uint32_t                  *data_fifo      = _core_if->data_fifo[0];
261
262                 gint_data_t        gintsts;
263                 hctsiz_data_t      hctsiz;
264                 hcchar_data_t      hcchar;
265                 haint_data_t       haint;
266                 hcint_data_t       hcint;
267                 grxsts_data_t      grxsts;
268
269                 /* Enable HAINTs */
270                 ifxusb_wreg(&hc_global_regs->haintmsk, 0x0001);
271
272                 /* Enable HCINTs */
273                 ifxusb_wreg(&hc_regs->hcintmsk, 0x04a3);
274
275                 /* Read GINTSTS */
276                 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
277                 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
278
279                 /* Read HAINT */
280                 haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
281                 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
282
283                 /* Read HCINT */
284                 hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
285                 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
286
287                 /* Read HCCHAR */
288                 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
289                 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
290
291                 /* Clear HCINT */
292                 ifxusb_wreg(&hc_regs->hcint, hcint.d32);
293
294                 /* Clear HAINT */
295                 ifxusb_wreg(&hc_global_regs->haint, haint.d32);
296
297                 /* Clear GINTSTS */
298                 ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
299
300                 /* Read GINTSTS */
301                 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
302                 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
303
304                 /*
305                  * Receive Control In packet
306                  */
307
308                 /* Make sure channel is disabled */
309                 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
310                 if (hcchar.b.chen) {
311                         //fprintf(stderr, "Channel already enabled 2, HCCHAR = %08x\n", hcchar.d32);
312                         hcchar.b.chdis = 1;
313                         hcchar.b.chen = 1;
314                         ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
315                         //sleep(1);
316                         mdelay(1000);
317
318                         /* Read GINTSTS */
319                         gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
320                         //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
321
322                         /* Read HAINT */
323                         haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
324                         //fprintf(stderr, "HAINT: %08x\n", haint.d32);
325
326                         /* Read HCINT */
327                         hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
328                         //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
329
330                         /* Read HCCHAR */
331                         hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
332                         //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
333
334                         /* Clear HCINT */
335                         ifxusb_wreg(&hc_regs->hcint, hcint.d32);
336
337                         /* Clear HAINT */
338                         ifxusb_wreg(&hc_global_regs->haint, haint.d32);
339
340                         /* Clear GINTSTS */
341                         ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
342
343                         hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
344                         //if (hcchar.b.chen) {
345                         //      fprintf(stderr, "** Channel _still_ enabled 2, HCCHAR = %08x **\n", hcchar.d32);
346                         //}
347                 }
348
349                 /* Set HCTSIZ */
350                 hctsiz.d32 = 0;
351                 hctsiz.b.xfersize = 8;
352                 hctsiz.b.pktcnt = 1;
353                 hctsiz.b.pid = IFXUSB_HC_PID_DATA1;
354                 ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
355
356                 /* Set HCCHAR */
357                 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
358                 hcchar.b.eptype = IFXUSB_EP_TYPE_CTRL;
359                 hcchar.b.epdir = 1;
360                 hcchar.b.epnum = 0;
361                 hcchar.b.mps = 8;
362                 hcchar.b.chen = 1;
363                 ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
364
365                 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
366                 //fprintf(stderr, "Waiting for RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
367
368                 /* Wait for receive status queue interrupt */
369                 do {
370                         gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
371                 } while (gintsts.b.rxstsqlvl == 0);
372
373                 //fprintf(stderr, "Got RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
374
375                 /* Read RXSTS */
376                 grxsts.d32 = ifxusb_rreg(&global_regs->grxstsp);
377                 //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
378
379                 /* Clear RXSTSQLVL in GINTSTS */
380                 gintsts.d32 = 0;
381                 gintsts.b.rxstsqlvl = 1;
382                 ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
383
384                 switch (grxsts.hb.pktsts) {
385                         case IFXUSB_HSTS_DATA_UPDT:
386                                 /* Read the data into the host buffer */
387                                 if (grxsts.hb.bcnt > 0) {
388                                         int i;
389                                         int word_count = (grxsts.hb.bcnt + 3) / 4;
390
391                                         for (i = 0; i < word_count; i++) {
392                                                 (void)ifxusb_rreg(data_fifo++);
393                                         }
394                                 }
395
396                                 //fprintf(stderr, "Received %u bytes\n", (unsigned)grxsts.hb.bcnt);
397                                 break;
398
399                         default:
400                                 //fprintf(stderr, "** Unexpected GRXSTS packet status 1 **\n");
401                                 break;
402                 }
403
404                 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
405                 //fprintf(stderr, "Waiting for RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
406
407                 /* Wait for receive status queue interrupt */
408                 do {
409                         gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
410                 } while (gintsts.b.rxstsqlvl == 0);
411
412                 //fprintf(stderr, "Got RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
413
414                 /* Read RXSTS */
415                 grxsts.d32 = ifxusb_rreg(&global_regs->grxstsp);
416                 //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
417
418                 /* Clear RXSTSQLVL in GINTSTS */
419                 gintsts.d32 = 0;
420                 gintsts.b.rxstsqlvl = 1;
421                 ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
422
423                 switch (grxsts.hb.pktsts) {
424                         case IFXUSB_HSTS_XFER_COMP:
425                                 break;
426
427                         default:
428                                 //fprintf(stderr, "** Unexpected GRXSTS packet status 2 **\n");
429                                 break;
430                 }
431
432                 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
433                 //fprintf(stderr, "Waiting for HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
434
435                 /* Wait for host channel interrupt */
436                 do {
437                         gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
438                 } while (gintsts.b.hcintr == 0);
439
440                 //fprintf(stderr, "Got HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
441
442                 /* Read HAINT */
443                 haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
444                 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
445
446                 /* Read HCINT */
447                 hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
448                 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
449
450                 /* Read HCCHAR */
451                 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
452                 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
453
454                 /* Clear HCINT */
455                 ifxusb_wreg(&hc_regs->hcint, hcint.d32);
456
457                 /* Clear HAINT */
458                 ifxusb_wreg(&hc_global_regs->haint, haint.d32);
459
460                 /* Clear GINTSTS */
461                 ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
462
463                 /* Read GINTSTS */
464                 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
465                 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
466
467         //      usleep(100000);
468         //      mdelay(100);
469                 mdelay(1);
470
471                 /*
472                  * Send handshake packet
473                  */
474
475                 /* Read HAINT */
476                 haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
477                 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
478
479                 /* Read HCINT */
480                 hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
481                 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
482
483                 /* Read HCCHAR */
484                 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
485                 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
486
487                 /* Clear HCINT */
488                 ifxusb_wreg(&hc_regs->hcint, hcint.d32);
489
490                 /* Clear HAINT */
491                 ifxusb_wreg(&hc_global_regs->haint, haint.d32);
492
493                 /* Clear GINTSTS */
494                 ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
495
496                 /* Read GINTSTS */
497                 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
498                 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
499
500                 /* Make sure channel is disabled */
501                 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
502                 if (hcchar.b.chen) {
503                         //fprintf(stderr, "Channel already enabled 3, HCCHAR = %08x\n", hcchar.d32);
504                         hcchar.b.chdis = 1;
505                         hcchar.b.chen = 1;
506                         ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
507                         //sleep(1);
508                         mdelay(1000);
509
510                         /* Read GINTSTS */
511                         gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
512                         //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
513
514                         /* Read HAINT */
515                         haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
516                         //fprintf(stderr, "HAINT: %08x\n", haint.d32);
517
518                         /* Read HCINT */
519                         hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
520                         //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
521
522                         /* Read HCCHAR */
523                         hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
524                         //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
525
526                         /* Clear HCINT */
527                         ifxusb_wreg(&hc_regs->hcint, hcint.d32);
528
529                         /* Clear HAINT */
530                         ifxusb_wreg(&hc_global_regs->haint, haint.d32);
531
532                         /* Clear GINTSTS */
533                         ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
534
535                         hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
536                         //if (hcchar.b.chen) {
537                         //      fprintf(stderr, "** Channel _still_ enabled 3, HCCHAR = %08x **\n", hcchar.d32);
538                         //}
539                 }
540
541                 /* Set HCTSIZ */
542                 hctsiz.d32 = 0;
543                 hctsiz.b.xfersize = 0;
544                 hctsiz.b.pktcnt = 1;
545                 hctsiz.b.pid = IFXUSB_HC_PID_DATA1;
546                 ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
547
548                 /* Set HCCHAR */
549                 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
550                 hcchar.b.eptype = IFXUSB_EP_TYPE_CTRL;
551                 hcchar.b.epdir = 0;
552                 hcchar.b.epnum = 0;
553                 hcchar.b.mps = 8;
554                 hcchar.b.chen = 1;
555                 ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
556
557                 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
558                 //fprintf(stderr, "Waiting for HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
559
560                 /* Wait for host channel interrupt */
561                 do {
562                         gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
563                 } while (gintsts.b.hcintr == 0);
564
565                 //fprintf(stderr, "Got HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
566
567                 /* Disable HCINTs */
568                 ifxusb_wreg(&hc_regs->hcintmsk, 0x0000);
569
570                 /* Disable HAINTs */
571                 ifxusb_wreg(&hc_global_regs->haintmsk, 0x0000);
572
573                 /* Read HAINT */
574                 haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
575                 //fprintf(stderr, "HAINT: %08x\n", haint.d32);
576
577                 /* Read HCINT */
578                 hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
579                 //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
580
581                 /* Read HCCHAR */
582                 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
583                 //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
584
585                 /* Clear HCINT */
586                 ifxusb_wreg(&hc_regs->hcint, hcint.d32);
587
588                 /* Clear HAINT */
589                 ifxusb_wreg(&hc_global_regs->haint, haint.d32);
590
591                 /* Clear GINTSTS */
592                 ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
593
594                 /* Read GINTSTS */
595                 gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
596                 //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
597         }
598 #endif //__WITH_HS_ELECT_TST__
599