ifxhcd_es.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  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. * This file contains code fragments from Synopsys HS OTG Linux Software Driver.
  29. * For this code the following notice is applicable:
  30. *
  31. * ==========================================================================
  32. *
  33. * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
  34. * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
  35. * otherwise expressly agreed to in writing between Synopsys and you.
  36. *
  37. * The Software IS NOT an item of Licensed Software or Licensed Product under
  38. * any End User Software License Agreement or Agreement for Licensed Product
  39. * with Synopsys or any supplement thereto. You are permitted to use and
  40. * redistribute this Software in source and binary forms, with or without
  41. * modification, provided that redistributions of source code must retain this
  42. * notice. You may not view, use, disclose, copy or distribute this file or
  43. * any information contained herein except pursuant to this license grant from
  44. * Synopsys. If you do not agree with this notice, including the disclaimer
  45. * below, then you are not authorized to use the Software.
  46. *
  47. * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
  48. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  49. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  50. * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
  51. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  52. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  53. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  54. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  55. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  56. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  57. * DAMAGE.
  58. * ========================================================================== */
  59. /*!
  60. \file ifxhcd_es.c
  61. \ingroup IFXUSB_DRIVER_V3
  62. \brief The file contain function to enable host mode USB-IF Electrical Test function.
  63. */
  64. #include <linux/version.h>
  65. #include "ifxusb_version.h"
  66. #include <linux/kernel.h>
  67. #include <linux/errno.h>
  68. #include <linux/dma-mapping.h>
  69. #include "ifxusb_plat.h"
  70. #include "ifxusb_regs.h"
  71. #include "ifxusb_cif.h"
  72. #include "ifxhcd.h"
  73. #ifdef __WITH_HS_ELECT_TST__
  74. /*
  75. * Quick and dirty hack to implement the HS Electrical Test
  76. * SINGLE_STEP_GET_DEVICE_DESCRIPTOR feature.
  77. *
  78. * This code was copied from our userspace app "hset". It sends a
  79. * Get Device Descriptor control sequence in two parts, first the
  80. * Setup packet by itself, followed some time later by the In and
  81. * Ack packets. Rather than trying to figure out how to add this
  82. * functionality to the normal driver code, we just hijack the
  83. * hardware, using these two function to drive the hardware
  84. * directly.
  85. */
  86. void do_setup(ifxusb_core_if_t *_core_if)
  87. {
  88. ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
  89. ifxusb_host_global_regs_t *hc_global_regs = _core_if->host_global_regs;
  90. ifxusb_hc_regs_t *hc_regs = _core_if->hc_regs[0];
  91. uint32_t *data_fifo = _core_if->data_fifo[0];
  92. gint_data_t gintsts;
  93. hctsiz_data_t hctsiz;
  94. hcchar_data_t hcchar;
  95. haint_data_t haint;
  96. hcint_data_t hcint;
  97. /* Enable HAINTs */
  98. ifxusb_wreg(&hc_global_regs->haintmsk, 0x0001);
  99. /* Enable HCINTs */
  100. ifxusb_wreg(&hc_regs->hcintmsk, 0x04a3);
  101. /* Read GINTSTS */
  102. gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
  103. //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
  104. /* Read HAINT */
  105. haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
  106. //fprintf(stderr, "HAINT: %08x\n", haint.d32);
  107. /* Read HCINT */
  108. hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
  109. //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
  110. /* Read HCCHAR */
  111. hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
  112. //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
  113. /* Clear HCINT */
  114. ifxusb_wreg(&hc_regs->hcint, hcint.d32);
  115. /* Clear HAINT */
  116. ifxusb_wreg(&hc_global_regs->haint, haint.d32);
  117. /* Clear GINTSTS */
  118. ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
  119. /* Read GINTSTS */
  120. gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
  121. //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
  122. /*
  123. * Send Setup packet (Get Device Descriptor)
  124. */
  125. /* Make sure channel is disabled */
  126. hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
  127. if (hcchar.b.chen) {
  128. //fprintf(stderr, "Channel already enabled 1, HCCHAR = %08x\n", hcchar.d32);
  129. hcchar.b.chdis = 1;
  130. // hcchar.b.chen = 1;
  131. ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
  132. //sleep(1);
  133. mdelay(1000);
  134. /* Read GINTSTS */
  135. gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
  136. //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
  137. /* Read HAINT */
  138. haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
  139. //fprintf(stderr, "HAINT: %08x\n", haint.d32);
  140. /* Read HCINT */
  141. hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
  142. //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
  143. /* Read HCCHAR */
  144. hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
  145. //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
  146. /* Clear HCINT */
  147. ifxusb_wreg(&hc_regs->hcint, hcint.d32);
  148. /* Clear HAINT */
  149. ifxusb_wreg(&hc_global_regs->haint, haint.d32);
  150. /* Clear GINTSTS */
  151. ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
  152. hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
  153. //if (hcchar.b.chen) {
  154. // fprintf(stderr, "** Channel _still_ enabled 1, HCCHAR = %08x **\n", hcchar.d32);
  155. //}
  156. }
  157. /* Set HCTSIZ */
  158. hctsiz.d32 = 0;
  159. hctsiz.b.xfersize = 8;
  160. hctsiz.b.pktcnt = 1;
  161. hctsiz.b.pid = IFXUSB_HC_PID_SETUP;
  162. ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
  163. /* Set HCCHAR */
  164. hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
  165. hcchar.b.eptype = IFXUSB_EP_TYPE_CTRL;
  166. hcchar.b.epdir = 0;
  167. hcchar.b.epnum = 0;
  168. hcchar.b.mps = 8;
  169. hcchar.b.chen = 1;
  170. ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
  171. /* Fill FIFO with Setup data for Get Device Descriptor */
  172. ifxusb_wreg(data_fifo++, 0x01000680);
  173. ifxusb_wreg(data_fifo++, 0x00080000);
  174. gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
  175. //fprintf(stderr, "Waiting for HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
  176. /* Wait for host channel interrupt */
  177. do {
  178. gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
  179. } while (gintsts.b.hcintr == 0);
  180. //fprintf(stderr, "Got HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
  181. /* Disable HCINTs */
  182. ifxusb_wreg(&hc_regs->hcintmsk, 0x0000);
  183. /* Disable HAINTs */
  184. ifxusb_wreg(&hc_global_regs->haintmsk, 0x0000);
  185. /* Read HAINT */
  186. haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
  187. //fprintf(stderr, "HAINT: %08x\n", haint.d32);
  188. /* Read HCINT */
  189. hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
  190. //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
  191. /* Read HCCHAR */
  192. hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
  193. //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
  194. /* Clear HCINT */
  195. ifxusb_wreg(&hc_regs->hcint, hcint.d32);
  196. /* Clear HAINT */
  197. ifxusb_wreg(&hc_global_regs->haint, haint.d32);
  198. /* Clear GINTSTS */
  199. ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
  200. /* Read GINTSTS */
  201. gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
  202. //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
  203. }
  204. void do_in_ack(ifxusb_core_if_t *_core_if)
  205. {
  206. ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
  207. ifxusb_host_global_regs_t *hc_global_regs = _core_if->host_global_regs;
  208. ifxusb_hc_regs_t *hc_regs = _core_if->hc_regs[0];
  209. uint32_t *data_fifo = _core_if->data_fifo[0];
  210. gint_data_t gintsts;
  211. hctsiz_data_t hctsiz;
  212. hcchar_data_t hcchar;
  213. haint_data_t haint;
  214. hcint_data_t hcint;
  215. grxsts_data_t grxsts;
  216. /* Enable HAINTs */
  217. ifxusb_wreg(&hc_global_regs->haintmsk, 0x0001);
  218. /* Enable HCINTs */
  219. ifxusb_wreg(&hc_regs->hcintmsk, 0x04a3);
  220. /* Read GINTSTS */
  221. gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
  222. //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
  223. /* Read HAINT */
  224. haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
  225. //fprintf(stderr, "HAINT: %08x\n", haint.d32);
  226. /* Read HCINT */
  227. hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
  228. //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
  229. /* Read HCCHAR */
  230. hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
  231. //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
  232. /* Clear HCINT */
  233. ifxusb_wreg(&hc_regs->hcint, hcint.d32);
  234. /* Clear HAINT */
  235. ifxusb_wreg(&hc_global_regs->haint, haint.d32);
  236. /* Clear GINTSTS */
  237. ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
  238. /* Read GINTSTS */
  239. gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
  240. //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
  241. /*
  242. * Receive Control In packet
  243. */
  244. /* Make sure channel is disabled */
  245. hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
  246. if (hcchar.b.chen) {
  247. //fprintf(stderr, "Channel already enabled 2, HCCHAR = %08x\n", hcchar.d32);
  248. hcchar.b.chdis = 1;
  249. hcchar.b.chen = 1;
  250. ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
  251. //sleep(1);
  252. mdelay(1000);
  253. /* Read GINTSTS */
  254. gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
  255. //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
  256. /* Read HAINT */
  257. haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
  258. //fprintf(stderr, "HAINT: %08x\n", haint.d32);
  259. /* Read HCINT */
  260. hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
  261. //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
  262. /* Read HCCHAR */
  263. hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
  264. //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
  265. /* Clear HCINT */
  266. ifxusb_wreg(&hc_regs->hcint, hcint.d32);
  267. /* Clear HAINT */
  268. ifxusb_wreg(&hc_global_regs->haint, haint.d32);
  269. /* Clear GINTSTS */
  270. ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
  271. hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
  272. //if (hcchar.b.chen) {
  273. // fprintf(stderr, "** Channel _still_ enabled 2, HCCHAR = %08x **\n", hcchar.d32);
  274. //}
  275. }
  276. /* Set HCTSIZ */
  277. hctsiz.d32 = 0;
  278. hctsiz.b.xfersize = 8;
  279. hctsiz.b.pktcnt = 1;
  280. hctsiz.b.pid = IFXUSB_HC_PID_DATA1;
  281. ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
  282. /* Set HCCHAR */
  283. hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
  284. hcchar.b.eptype = IFXUSB_EP_TYPE_CTRL;
  285. hcchar.b.epdir = 1;
  286. hcchar.b.epnum = 0;
  287. hcchar.b.mps = 8;
  288. hcchar.b.chen = 1;
  289. ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
  290. gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
  291. //fprintf(stderr, "Waiting for RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
  292. /* Wait for receive status queue interrupt */
  293. do {
  294. gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
  295. } while (gintsts.b.rxstsqlvl == 0);
  296. //fprintf(stderr, "Got RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
  297. /* Read RXSTS */
  298. grxsts.d32 = ifxusb_rreg(&global_regs->grxstsp);
  299. //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
  300. /* Clear RXSTSQLVL in GINTSTS */
  301. gintsts.d32 = 0;
  302. gintsts.b.rxstsqlvl = 1;
  303. ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
  304. switch (grxsts.hb.pktsts) {
  305. case IFXUSB_HSTS_DATA_UPDT:
  306. /* Read the data into the host buffer */
  307. if (grxsts.hb.bcnt > 0) {
  308. int i;
  309. int word_count = (grxsts.hb.bcnt + 3) / 4;
  310. for (i = 0; i < word_count; i++) {
  311. (void)ifxusb_rreg(data_fifo++);
  312. }
  313. }
  314. //fprintf(stderr, "Received %u bytes\n", (unsigned)grxsts.hb.bcnt);
  315. break;
  316. default:
  317. //fprintf(stderr, "** Unexpected GRXSTS packet status 1 **\n");
  318. break;
  319. }
  320. gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
  321. //fprintf(stderr, "Waiting for RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
  322. /* Wait for receive status queue interrupt */
  323. do {
  324. gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
  325. } while (gintsts.b.rxstsqlvl == 0);
  326. //fprintf(stderr, "Got RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
  327. /* Read RXSTS */
  328. grxsts.d32 = ifxusb_rreg(&global_regs->grxstsp);
  329. //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
  330. /* Clear RXSTSQLVL in GINTSTS */
  331. gintsts.d32 = 0;
  332. gintsts.b.rxstsqlvl = 1;
  333. ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
  334. switch (grxsts.hb.pktsts) {
  335. case IFXUSB_HSTS_XFER_COMP:
  336. break;
  337. default:
  338. //fprintf(stderr, "** Unexpected GRXSTS packet status 2 **\n");
  339. break;
  340. }
  341. gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
  342. //fprintf(stderr, "Waiting for HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
  343. /* Wait for host channel interrupt */
  344. do {
  345. gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
  346. } while (gintsts.b.hcintr == 0);
  347. //fprintf(stderr, "Got HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
  348. /* Read HAINT */
  349. haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
  350. //fprintf(stderr, "HAINT: %08x\n", haint.d32);
  351. /* Read HCINT */
  352. hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
  353. //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
  354. /* Read HCCHAR */
  355. hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
  356. //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
  357. /* Clear HCINT */
  358. ifxusb_wreg(&hc_regs->hcint, hcint.d32);
  359. /* Clear HAINT */
  360. ifxusb_wreg(&hc_global_regs->haint, haint.d32);
  361. /* Clear GINTSTS */
  362. ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
  363. /* Read GINTSTS */
  364. gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
  365. //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
  366. // usleep(100000);
  367. // mdelay(100);
  368. mdelay(1);
  369. /*
  370. * Send handshake packet
  371. */
  372. /* Read HAINT */
  373. haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
  374. //fprintf(stderr, "HAINT: %08x\n", haint.d32);
  375. /* Read HCINT */
  376. hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
  377. //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
  378. /* Read HCCHAR */
  379. hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
  380. //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
  381. /* Clear HCINT */
  382. ifxusb_wreg(&hc_regs->hcint, hcint.d32);
  383. /* Clear HAINT */
  384. ifxusb_wreg(&hc_global_regs->haint, haint.d32);
  385. /* Clear GINTSTS */
  386. ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
  387. /* Read GINTSTS */
  388. gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
  389. //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
  390. /* Make sure channel is disabled */
  391. hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
  392. if (hcchar.b.chen) {
  393. //fprintf(stderr, "Channel already enabled 3, HCCHAR = %08x\n", hcchar.d32);
  394. hcchar.b.chdis = 1;
  395. hcchar.b.chen = 1;
  396. ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
  397. //sleep(1);
  398. mdelay(1000);
  399. /* Read GINTSTS */
  400. gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
  401. //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
  402. /* Read HAINT */
  403. haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
  404. //fprintf(stderr, "HAINT: %08x\n", haint.d32);
  405. /* Read HCINT */
  406. hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
  407. //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
  408. /* Read HCCHAR */
  409. hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
  410. //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
  411. /* Clear HCINT */
  412. ifxusb_wreg(&hc_regs->hcint, hcint.d32);
  413. /* Clear HAINT */
  414. ifxusb_wreg(&hc_global_regs->haint, haint.d32);
  415. /* Clear GINTSTS */
  416. ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
  417. hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
  418. //if (hcchar.b.chen) {
  419. // fprintf(stderr, "** Channel _still_ enabled 3, HCCHAR = %08x **\n", hcchar.d32);
  420. //}
  421. }
  422. /* Set HCTSIZ */
  423. hctsiz.d32 = 0;
  424. hctsiz.b.xfersize = 0;
  425. hctsiz.b.pktcnt = 1;
  426. hctsiz.b.pid = IFXUSB_HC_PID_DATA1;
  427. ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
  428. /* Set HCCHAR */
  429. hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
  430. hcchar.b.eptype = IFXUSB_EP_TYPE_CTRL;
  431. hcchar.b.epdir = 0;
  432. hcchar.b.epnum = 0;
  433. hcchar.b.mps = 8;
  434. hcchar.b.chen = 1;
  435. ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
  436. gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
  437. //fprintf(stderr, "Waiting for HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
  438. /* Wait for host channel interrupt */
  439. do {
  440. gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
  441. } while (gintsts.b.hcintr == 0);
  442. //fprintf(stderr, "Got HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
  443. /* Disable HCINTs */
  444. ifxusb_wreg(&hc_regs->hcintmsk, 0x0000);
  445. /* Disable HAINTs */
  446. ifxusb_wreg(&hc_global_regs->haintmsk, 0x0000);
  447. /* Read HAINT */
  448. haint.d32 = ifxusb_rreg(&hc_global_regs->haint);
  449. //fprintf(stderr, "HAINT: %08x\n", haint.d32);
  450. /* Read HCINT */
  451. hcint.d32 = ifxusb_rreg(&hc_regs->hcint);
  452. //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
  453. /* Read HCCHAR */
  454. hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
  455. //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
  456. /* Clear HCINT */
  457. ifxusb_wreg(&hc_regs->hcint, hcint.d32);
  458. /* Clear HAINT */
  459. ifxusb_wreg(&hc_global_regs->haint, haint.d32);
  460. /* Clear GINTSTS */
  461. ifxusb_wreg(&global_regs->gintsts, gintsts.d32);
  462. /* Read GINTSTS */
  463. gintsts.d32 = ifxusb_rreg(&global_regs->gintsts);
  464. //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
  465. }
  466. #endif //__WITH_HS_ELECT_TST__