Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

698 lines
20 KiB

  1. /*++
  2. Module Name:
  3. mxload.C
  4. Abstract:
  5. The module contains the functions that download the
  6. firmware code to hardware.
  7. Environment:
  8. kernel mode only
  9. Notes:
  10. Revision History:
  11. --*/
  12. #include <ntddk.h>
  13. #include <wdmguid.h>
  14. #include <ntddser.h>
  15. #include <initguid.h>
  16. #include "mxenum.h"
  17. #define BIOS 0
  18. #define BOARD_FIRMWARE 1
  19. #define MODULE_FIRMWARE 2
  20. //
  21. // for C218 BIOS initialization
  22. //
  23. #define C218_ConfBase 0x800
  24. #define C218_status (C218_ConfBase + 0) /* BIOS running status */
  25. #define C218_diag (C218_ConfBase + 2) /* diagnostic status */
  26. #define C218_key (C218_ConfBase + 4) /* WORD (0x218 for C218)*/
  27. #define C218DLoad_len (C218_ConfBase + 6) /* WORD */
  28. #define C218check_sum (C218_ConfBase + 8) /* BYTE */
  29. #define C218chksum_ok (C218_ConfBase + 0x0a) /* BYTE (1:ok) */
  30. #define C218_TestRx (C218_ConfBase + 0x10) /* 8 bytes for 8 ports */
  31. #define C218_TestTx (C218_ConfBase + 0x18) /* 8 bytes for 8 ports */
  32. #define C218_RXerr (C218_ConfBase + 0x20) /* 8 bytes for 8 ports */
  33. #define C218_ErrFlag (C218_ConfBase + 0x28) /* 8 bytes for 8 ports */
  34. #define C218_TestCnt C218_ConfBase + 0x30 /* 8 words for 8 ports */
  35. #define C218_LoadBuf 0x0f00
  36. #define C218_KeyCode 0x218
  37. #define CP204J_KeyCode 0x204
  38. /*
  39. * for C320 BIOS initialization
  40. */
  41. #define C320_ConfBase 0x800
  42. #define C320_status C320_ConfBase + 0 /* BIOS running status */
  43. #define C320_diag C320_ConfBase + 2 /* diagnostic status */
  44. #define C320_key C320_ConfBase + 4 /* WORD (0320H for C320)*/
  45. #define C320DLoad_len C320_ConfBase + 6 /* WORD */
  46. #define C320check_sum C320_ConfBase + 8 /* WORD */
  47. #define C320chksum_ok C320_ConfBase + 0x0a /* WORD (1:ok) */
  48. #define C320bapi_len C320_ConfBase + 0x0c /* WORD */
  49. #define C320UART_no C320_ConfBase + 0x0e /* WORD */
  50. #define STS_init 0x05 /* for C320_status */
  51. #define C320_LoadBuf 0x0f00
  52. #define C320_KeyCode 0x320
  53. #define FixPage_addr 0x0000 /* starting addr of static page */
  54. #define DynPage_addr 0x2000 /* starting addr of dynamic page */
  55. #define Control_reg 0x1ff0 /* select page and reset control */
  56. #define HW_reset 0x80
  57. //
  58. // Dual-Ported RAM
  59. //
  60. #define DRAM_global 0
  61. #define INT_data (DRAM_global + 0)
  62. #define Config_base (DRAM_global + 0x108)
  63. //
  64. #define Magic_code 0x404
  65. #define Magic_no (Config_base + 0)
  66. #define Card_model_no (Config_base + 2)
  67. #define Total_ports (Config_base + 4)
  68. #define C320B_len (Config_base + 6)
  69. #define Module_cnt (Config_base + 8)
  70. #define Module_no (Config_base + 10)
  71. #define C320B_restart (Config_base + 12)
  72. #define Card_Exist (Config_base + 14)
  73. #define Disable_Irq (Config_base + 20)
  74. #define TMS320Port1 (Config_base + 22)
  75. #define TMS320Port2 (Config_base + 24)
  76. #define TMS320Clock (Config_base + 26)
  77. //
  78. // DATA BUFFER in DRAM
  79. //
  80. #define Extern_table 0x400 /* Base address of the external table
  81. (24 words * 64) total 3K bytes
  82. (24 words * 128) total 6K bytes */
  83. #define Extern_size 0x60 /* 96 bytes */
  84. #define RXrptr 0 /* read pointer for RX buffer */
  85. #define RXwptr 2 /* write pointer for RX buffer */
  86. #define TXrptr 4 /* read pointer for TX buffer */
  87. #define TXwptr 6 /* write pointer for TX buffer */
  88. #define HostStat 8 /* IRQ flag and general flag */
  89. #define FlagStat 10
  90. #define Flow_control 0x0C /* B7 B6 B5 B4 B3 B2 B1 B0 */
  91. /* x x x x | | | | */
  92. /* | | | + CTS flow */
  93. /* | | +--- RTS flow */
  94. /* | +------ TX Xon/Xoff*/
  95. /* +--------- RX Xon/Xoff*/
  96. #define Break_cnt 0x0e /* received break count */
  97. #define CD180TXirq 0x10 /* if non-0: enable TX irq */
  98. #define RX_mask 0x12
  99. #define TX_mask 0x14
  100. #define Ofs_rxb 0x16
  101. #define Ofs_txb 0x18
  102. #define Page_rxb 0x1A
  103. #define Page_txb 0x1C
  104. #define EndPage_rxb 0x1E
  105. #define EndPage_txb 0x20
  106. #define C218rx_size 0x2000 /* 8K bytes */
  107. #define C218tx_size 0x8000 /* 32K bytes */
  108. #define C218rx_mask (C218rx_size - 1)
  109. #define C218tx_mask (C218tx_size - 1)
  110. #define C320p8rx_size 0x2000
  111. #define C320p8tx_size 0x8000
  112. #define C320p8rx_mask (C320p8rx_size - 1)
  113. #define C320p8tx_mask (C320p8tx_size - 1)
  114. #define C320p16rx_size 0x2000
  115. #define C320p16tx_size 0x4000
  116. #define C320p16rx_mask (C320p16rx_size - 1)
  117. #define C320p16tx_mask (C320p16tx_size - 1)
  118. #define C320p24rx_size 0x2000
  119. #define C320p24tx_size 0x2000
  120. #define C320p24rx_mask (C320p24rx_size - 1)
  121. #define C320p24tx_mask (C320p24tx_size - 1)
  122. #define C320p32rx_size 0x1000
  123. #define C320p32tx_size 0x1000
  124. #define C320p32rx_mask (C320p32rx_size - 1)
  125. #define C320p32tx_mask (C320p32tx_size - 1)
  126. #define Page_size 0x2000
  127. #define Page_mask (Page_size - 1)
  128. #define C218rx_spage 3
  129. #define C218tx_spage 4
  130. #define C218rx_pageno 1
  131. #define C218tx_pageno 4
  132. #define C218buf_pageno 5
  133. #define C320p8rx_spage 3
  134. #define C320p8tx_spage 4
  135. #define C320p8rx_pgno 1
  136. #define C320p8tx_pgno 4
  137. #define C320p8buf_pgno 5
  138. #define C320p16rx_spage 3
  139. #define C320p16tx_spage 4
  140. #define C320p16rx_pgno 1
  141. #define C320p16tx_pgno 2
  142. #define C320p16buf_pgno 3
  143. #define C320p24rx_spage 3
  144. #define C320p24tx_spage 4
  145. #define C320p24rx_pgno 1
  146. #define C320p24tx_pgno 1
  147. #define C320p24buf_pgno 2
  148. #define C320p32rx_spage 3
  149. #define C320p32tx_ofs C320p32rx_size
  150. #define C320p32tx_spage 3
  151. #define C320p32buf_pgno 1
  152. USHORT FirmwareBoardType[MOXA_MAX_BOARD_TYPE] = {
  153. 1, // C218Turbo
  154. 1, // C218Turbo/PCI
  155. 2, // C320Turbo
  156. 2, // C320Turbo/PCI
  157. 3 // CP-204J
  158. };
  159. USHORT C320rx_mask[4] = {
  160. C320p8rx_mask,
  161. C320p16rx_mask,
  162. C320p24rx_mask,
  163. C320p32rx_mask
  164. };
  165. USHORT C320tx_mask[4] = {
  166. C320p8tx_mask,
  167. C320p16tx_mask,
  168. C320p24tx_mask,
  169. C320p32tx_mask
  170. };
  171. USHORT C320tx_ofs[4] = {
  172. 0,
  173. 0,
  174. 0,
  175. C320p32tx_ofs
  176. };
  177. USHORT C320rx_spage[4] = {
  178. C320p8rx_spage,
  179. C320p16rx_spage,
  180. C320p24rx_spage,
  181. C320p32rx_spage
  182. };
  183. USHORT C320tx_spage[4] = {
  184. C320p8tx_spage,
  185. C320p16tx_spage,
  186. C320p24tx_spage,
  187. C320p32tx_spage
  188. };
  189. USHORT C320buf_pgno[4] = {
  190. C320p8buf_pgno,
  191. C320p16buf_pgno,
  192. C320p24buf_pgno,
  193. C320p32buf_pgno
  194. };
  195. USHORT C320tx_pgno[4] = {
  196. C320p8tx_pgno,
  197. C320p16tx_pgno,
  198. 0,
  199. 0
  200. };
  201. UCHAR fileHead[32];
  202. int
  203. MxenumDownloadFirmware(PFDO_DEVICE_DATA DeviceData,BOOLEAN NumPortDefined)
  204. {
  205. HANDLE hfile;
  206. NTSTATUS status;
  207. PWCHAR fileName;
  208. PUCHAR buffer;
  209. PUCHAR ofs,base = DeviceData->BaseAddress;
  210. ULONG size[3],len, i,j,len1,len2,numread;
  211. USHORT retry;
  212. PUSHORT uptr;
  213. USHORT usum,module,keycode;
  214. switch (DeviceData->BoardType) {
  215. case C218ISA :
  216. case C218PCI :
  217. fileName = L"\\SystemRoot\\System32\\c218tnt.cod";
  218. len = 32; // the length of firmware file head
  219. keycode = C218_KeyCode;
  220. break;
  221. case CP204J :
  222. fileName = L"\\SystemRoot\\System32\\cp204jnt.cod";
  223. len = 32; // the length of firmware file head
  224. keycode = CP204J_KeyCode;
  225. break;
  226. case C320ISA :
  227. case C320PCI :
  228. fileName = L"\\SystemRoot\\System32\\c320tnt.cod";
  229. len = 32; // the length of firmware file head
  230. keycode = C320_KeyCode;
  231. break;
  232. default :
  233. return(Fail_Download);
  234. }
  235. if (!DeviceData->BaseAddress)
  236. return(Fail_Download);
  237. status = MxenumOpenFile(fileName, TRUE, &hfile);
  238. if (!NT_SUCCESS(status)) {
  239. MxenumKdPrint (MXENUM_DBG_TRACE,("DownloadFirmware: open fail\n"));
  240. status = Fail_FirmwareCode;
  241. return(status);
  242. }
  243. numread = 0;
  244. status = MxenumReadFile(hfile, fileHead, len, &numread);
  245. if (!NT_SUCCESS(status) || (numread != len)) {
  246. MxenumKdPrint (MXENUM_DBG_TRACE,("DownloadFirmware: read file head fail\n"));
  247. MxenumCloseFile(hfile);
  248. status = Fail_FirmwareCode;
  249. return(status);
  250. }
  251. if ((fileHead[0] != '4') || (fileHead[1] != '0') ||
  252. (fileHead[2] != '4') || (fileHead[3] != '0') ||
  253. (fileHead[7] != FirmwareBoardType[DeviceData->BoardType-1]) ||
  254. (fileHead[6] != 2)) { // fileHead[6] == 2 for NT
  255. MxenumKdPrint (MXENUM_DBG_TRACE,("DownloadFirmware: invalid file head\n"));
  256. status = Fail_FirmwareCode;
  257. MxenumCloseFile(hfile);
  258. return(status);
  259. }
  260. switch (DeviceData->BoardType) {
  261. case C218ISA :
  262. case C218PCI :
  263. case CP204J :
  264. len = 0;
  265. for (i = 0; i < 2; i++) {
  266. size[i] = fileHead[17+i*2];
  267. size[i] <<= 8;
  268. size[i] += fileHead[16+i*2];
  269. if (size[i] <= 0) {
  270. MxenumKdPrint (MXENUM_DBG_TRACE,("DownloadFirmware: invalid file head\n"));
  271. status = Fail_FirmwareCode;
  272. MxenumCloseFile(hfile);
  273. return(status);
  274. }
  275. if (size[i] > len)
  276. len = size[i];
  277. }
  278. break;
  279. default :
  280. len = 0;
  281. for (i = 0; i < 3; i++) {
  282. size[i] = fileHead[17+i*2];
  283. size[i] <<= 8;
  284. size[i] += fileHead[16+i*2];
  285. if (size[i] <= 0) {
  286. MxenumKdPrint (MXENUM_DBG_TRACE,("DownloadFirmware: invalid file head\n"));
  287. status = Fail_FirmwareCode;
  288. MxenumCloseFile(hfile);
  289. return(status);
  290. }
  291. if (size[i] > len)
  292. len = size[i];
  293. }
  294. break;
  295. }
  296. buffer = ExAllocatePool(PagedPool, len);
  297. if (!buffer) {
  298. MxenumKdPrint (MXENUM_DBG_TRACE,("DownloadFirmware: unable to allocate buffer size = %d\n",len));
  299. status = Fail_Download;
  300. MxenumCloseFile(hfile);
  301. return(status);
  302. }
  303. // ****************start to download bios
  304. status = 0;
  305. // the data len of bios code
  306. len = size[BIOS];
  307. status = MxenumReadFile(hfile, buffer, len, &numread);
  308. if (!NT_SUCCESS(status) || (numread != len)) {
  309. MxenumKdPrint (MXENUM_DBG_TRACE,("DownloadFirmware: read bios code fail\n"));
  310. status = Fail_FirmwareCode;
  311. goto DownloadFirmwareDone;
  312. }
  313. base[Control_reg] = HW_reset; /* reset */
  314. MxenumDelay(5); /* delay 10ms */
  315. for (i=0; i<4096; i++)
  316. base[i] = 0;
  317. for (i=0; i<len; i++)
  318. base[i] = buffer[i]; /* download BIOS */
  319. base[Control_reg] = 0; /* release reset */
  320. // start to finding board
  321. MxenumDelay(1000); /* delay 2 secs */
  322. switch (DeviceData->BoardType) {
  323. case C218ISA:
  324. case C218PCI :
  325. case CP204J:
  326. retry = 0;
  327. while (*(PUSHORT)(base + C218_key) != keycode) {
  328. MxenumDelay(1);
  329. if (retry++ > 50) /* wait for 100ms */
  330. break;
  331. }
  332. if (*(PUSHORT)(base + C218_key) != keycode) {
  333. MxenumKdPrint (MXENUM_DBG_TRACE,("DownloadFirmware: unable to find c218 board = %d\n",len));
  334. status = Fail_FindBoard;
  335. goto DownloadFirmwareDone;
  336. }
  337. break;
  338. default:
  339. retry = 0;
  340. while (*(PUSHORT)(base + C320_key) != keycode) {
  341. MxenumDelay(1);
  342. if (retry++ > 50) /* wait for 100ms */
  343. break;
  344. }
  345. if (*(PUSHORT)(base + C320_key) != keycode) {
  346. MxenumKdPrint (MXENUM_DBG_TRACE,("DownloadFirmware: unable to find c320 board = %d\n",len));
  347. status = Fail_FindBoard;
  348. goto DownloadFirmwareDone;
  349. }
  350. retry = 0;
  351. while (*(PUSHORT)(base + C320_status) != STS_init) {
  352. MxenumDelay(1);
  353. if (retry++ > 1500) /* wait for 3s */
  354. break;
  355. }
  356. if (*(PUSHORT)(base + C320_status) != STS_init) {
  357. MxenumKdPrint (MXENUM_DBG_TRACE,("DownloadFirmware: unable to find c320 board = %d\n",len));
  358. status = Fail_FindCpumodule;
  359. goto DownloadFirmwareDone;
  360. }
  361. // start to download firmware of C320 board
  362. len = size[BOARD_FIRMWARE]; // the data len of C320 board firmware code
  363. status = MxenumReadFile(hfile, buffer, len, &numread);
  364. if (!NT_SUCCESS(status) || (numread != len)) {
  365. MxenumKdPrint (MXENUM_DBG_TRACE,("DownloadFirmware: read c320 board firmware code fail\n"));
  366. status = Fail_FirmwareCode;
  367. goto DownloadFirmwareDone;
  368. }
  369. *(PUSHORT)&base[C320bapi_len] = (USHORT)(len - 7168 - 2);
  370. base[Control_reg] = 1; /* Select Page 1 */
  371. for (i=0; i<7168; i++)
  372. base[DynPage_addr + i] = buffer[i];
  373. base[Control_reg] = 2; /* Select Page 2 */
  374. for (i=0; i<(len - 7168); i++)
  375. base[DynPage_addr + i] = buffer[i+7168];
  376. break;
  377. }
  378. // start to downloading firmware
  379. MxenumKdPrint (MXENUM_DBG_TRACE,("DownloadFirmware: start to download firmware\n"));
  380. // the data len of firmware code
  381. switch (DeviceData->BoardType) {
  382. case C218ISA:
  383. case C218PCI :
  384. case CP204J:
  385. len = size[BOARD_FIRMWARE];
  386. break;
  387. default :
  388. len = size[MODULE_FIRMWARE];
  389. break;
  390. }
  391. status = MxenumReadFile(hfile, buffer, len, &numread);
  392. if (!NT_SUCCESS(status) || (numread != len)) {
  393. MxenumKdPrint (MXENUM_DBG_TRACE,("DownloadFirmware: read firmware code fail\n"));
  394. status = Fail_FirmwareCode;
  395. goto DownloadFirmwareDone;
  396. }
  397. retry = 0;
  398. switch (DeviceData->BoardType) {
  399. case C218ISA:
  400. case C218PCI :
  401. case CP204J:
  402. do {
  403. j = 0;
  404. usum = 0;
  405. len1 = len >> 1;
  406. uptr = (PUSHORT)buffer;
  407. for (i=0; i<len1; i++)
  408. usum += uptr[i];
  409. while (len1) {
  410. if (len1 > 2048)
  411. len2 = 2048;
  412. else
  413. len2 = len1;
  414. len1 -= len2;
  415. for (i=0; i<len2<<1; i++)
  416. base[C218_LoadBuf+i] = buffer[j+i];
  417. j += i;
  418. *(PUSHORT)&(base[C218DLoad_len]) = (USHORT)len2;
  419. *(PUSHORT)&(base[C218_key]) = 0;
  420. for (i=0; i<100; i++) {
  421. if (*(PUSHORT)&(base[C218_key]) == keycode)
  422. break;
  423. MxenumDelay(1);
  424. }
  425. if (*(PUSHORT)&(base[C218_key]) != keycode) {
  426. status = Fail_Download;
  427. goto DownloadFirmwareDone;
  428. }
  429. }
  430. *(PUSHORT)&base[C218DLoad_len] = 0;
  431. *(PUSHORT)&base[C218check_sum] = usum;
  432. *(PUSHORT)&base[C218_key] = 0;
  433. for (i=0; i<100; i++) {
  434. if (*(PUSHORT)&base[C218_key] == keycode)
  435. break;
  436. MxenumDelay(1);
  437. }
  438. retry++;
  439. } while ((base[C218chksum_ok] != 1) && (retry < 3));
  440. if (base[C218chksum_ok] != 1) {
  441. status = Fail_Checksum;
  442. goto DownloadFirmwareDone;
  443. }
  444. *(PUSHORT)&base[C218_key] = 0;
  445. for (i=0; i<100; i++) {
  446. if (*(PUSHORT)&base[Magic_no] == Magic_code)
  447. break;
  448. MxenumDelay(1);
  449. }
  450. if (*(PUSHORT)&base[Magic_no] != Magic_code) {
  451. status = Fail_Download;
  452. goto DownloadFirmwareDone;
  453. }
  454. *(PUSHORT)&base[Disable_Irq] = 0;
  455. *(PUSHORT)&base[Magic_no] = 0;
  456. for (i=0; i<100; i++) {
  457. if (*(PUSHORT)&base[Magic_no] == Magic_code)
  458. break;
  459. MxenumDelay(1);
  460. }
  461. if (*(PUSHORT)&base[Magic_no] != Magic_code) {
  462. status = Fail_Download;
  463. goto DownloadFirmwareDone;
  464. }
  465. for (i=0; i<DeviceData->NumPorts; i++) {
  466. ofs = base + Extern_table + Extern_size * i;
  467. *(PUSHORT)(ofs + RX_mask) = C218rx_mask;
  468. *(PUSHORT)(ofs + TX_mask) = C218tx_mask;
  469. *(PUSHORT)(ofs + Page_rxb) = (USHORT)(C218rx_spage + i * C218buf_pageno);
  470. *(PUSHORT)(ofs + EndPage_rxb) = *(PUSHORT)(ofs + Page_rxb) + C218rx_pageno;
  471. *(PUSHORT)(ofs + Page_txb) = (USHORT)(C218tx_spage + i * C218buf_pageno);
  472. *(PUSHORT)(ofs + EndPage_txb) = *(PUSHORT)(ofs + Page_txb) + C218tx_pageno;
  473. }
  474. break;
  475. default :
  476. do {
  477. j = 0;
  478. usum = 0;
  479. len1 = len >> 1;
  480. uptr = (PUSHORT)buffer;
  481. for (i=0; i<len1; i++)
  482. usum += uptr[i];
  483. while (len1) {
  484. if (len1 > 2048)
  485. len2 = 2048;
  486. else
  487. len2 = len1;
  488. len1 -= len2;
  489. for (i=0; i<len2<<1; i++)
  490. base[C320_LoadBuf+i] = buffer[j+i];
  491. j += i;
  492. *(PUSHORT)&(base[C320DLoad_len]) = (USHORT)len2;
  493. *(PUSHORT)&(base[C320_key]) = 0;
  494. for (i=0; i<100; i++) {
  495. if (*(PUSHORT)&(base[C320_key]) == keycode)
  496. break;
  497. MxenumDelay(1);
  498. }
  499. if (*(PUSHORT)&(base[C320_key]) != keycode) {
  500. status = Fail_Download;
  501. goto DownloadFirmwareDone;
  502. }
  503. }
  504. *(PUSHORT)&base[C320DLoad_len] = 0;
  505. *(PUSHORT)&base[C320check_sum] = usum;
  506. *(PUSHORT)&(base[C320_key]) = 0;
  507. for (i=0; i<100; i++) {
  508. if (*(PUSHORT)&(base[C320_key]) == keycode)
  509. break;
  510. MxenumDelay(1);
  511. }
  512. retry++;
  513. } while ((base[C320chksum_ok] != 1) && (retry < 3));
  514. if (base[C320chksum_ok] != 1) {
  515. status = Fail_Checksum;
  516. goto DownloadFirmwareDone;
  517. }
  518. *(PUSHORT)&(base[C320_key]) = 0;
  519. for (i=0; i<100; i++) {
  520. if (*(PUSHORT)&base[Magic_no] == Magic_code)
  521. break;
  522. MxenumDelay(1); /* delay 2 ms */
  523. }
  524. if (*(PUSHORT)&base[Magic_no] != Magic_code) {
  525. status = Fail_Download;
  526. goto DownloadFirmwareDone;
  527. }
  528. *(PUSHORT)&base[Disable_Irq] = 0;
  529. if (DeviceData->InterfaceType == PCIBus) {// ASIC board
  530. *(PUSHORT)&base[TMS320Port1] = 0x3800;
  531. *(PUSHORT)&base[TMS320Port2] = 0x3900;
  532. *(PUSHORT)&base[TMS320Clock] = 28499; // 57 MHZ
  533. }
  534. else {
  535. *(PUSHORT)&base[TMS320Port1] = 0x3200;
  536. *(PUSHORT)&base[TMS320Port2] = 0x3400;
  537. *(PUSHORT)&base[TMS320Clock] = 19999; // 40 MHZ
  538. }
  539. *(PUSHORT)&base[Magic_no] = 0;
  540. for (i=0; i<100; i++) {
  541. if (*(PUSHORT)&base[Magic_no] == Magic_code)
  542. break;
  543. MxenumDelay(1); /* delay 2 ms */
  544. }
  545. if (*(PUSHORT)&base[Magic_no] != Magic_code)
  546. return(Fail_Cpumodule);
  547. if (NumPortDefined == FALSE) {// it means the fisrt time install
  548. DeviceData->NumPorts = 8*base[Module_cnt];
  549. module = base[Module_cnt];
  550. }
  551. else {
  552. module = (USHORT)(DeviceData->NumPorts/8);
  553. if (base[Module_cnt] < module)
  554. return(Fail_Uartmodule);
  555. }
  556. *(PUSHORT)&base[Module_no] = module;
  557. *(PUSHORT)&base[Magic_no] = 0;
  558. for (i=0; i<100; i++) {
  559. if (*(PUSHORT)&base[Magic_no] == Magic_code)
  560. break;
  561. MxenumDelay(1); /* delay 2 ms */
  562. }
  563. if (*(PUSHORT)&base[Magic_no] != Magic_code) {
  564. status = Fail_Download;
  565. goto DownloadFirmwareDone;
  566. }
  567. for (i=0; i<DeviceData->NumPorts; i++) {
  568. ofs = base + Extern_table + Extern_size * i;
  569. *(PUSHORT)(ofs + RX_mask) = C320rx_mask[module-1];
  570. *(PUSHORT)(ofs + TX_mask) = C320tx_mask[module-1];
  571. *(PUSHORT)(ofs + Ofs_txb) = C320tx_ofs[module-1];
  572. *(PUSHORT)(ofs + Page_rxb) = (USHORT)(C320rx_spage[module-1] + i * C320buf_pgno[module-1]);
  573. *(PUSHORT)(ofs + EndPage_rxb) = *(PUSHORT)(ofs + Page_rxb);
  574. *(PUSHORT)(ofs + Page_txb) = (USHORT)(C320tx_spage[module-1] + i * C320buf_pgno[module-1]);
  575. *(PUSHORT)(ofs + EndPage_txb) = *(PUSHORT)(ofs + Page_txb) + C320tx_pgno[module-1];
  576. }
  577. break;
  578. }
  579. DownloadFirmwareDone :;
  580. ExFreePool(buffer);
  581. MxenumCloseFile(hfile);
  582. MxenumKdPrint (MXENUM_DBG_TRACE,("DownloadFirmware: exit=%x\n",status));
  583. return (status);
  584. }