bri.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:18k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (C) Eicon Technology Corporation, 2000.
  3.  *
  4.  * Eicon File Revision :    1.8  
  5.  *
  6.  * This software may be used and distributed according to the terms
  7.  * of the GNU General Public License, incorporated herein by reference.
  8.  *
  9.  */
  10. #include "eicon.h"
  11. #include "sys.h"
  12. #include "idi.h"
  13. #include "divas.h"
  14. #include "pc.h"
  15. #include "pr_pc.h"
  16. #include "dsp_defs.h"
  17. #include "adapter.h"
  18. #include "uxio.h"
  19. #define PCI_BADDR0 0x10
  20. #define PCI_BADDR1 0x14
  21. #define PCI_BADDR2 0x18
  22. #define DIVAS_SIGNATURE 0x4447
  23. /* offset to start of MAINT area (used by xlog) */
  24. #define DIVAS_MAINT_OFFSET 0xff00 /* value for BRI card */
  25. #define PROTCAP_TELINDUS 0x1
  26. #define PROTCAP_V90D 0x8
  27. word GetProtFeatureValue(char *sw_id);
  28. byte io_in(ADAPTER *a, void *adr);
  29. word io_inw(ADAPTER *a, void *adr);
  30. void io_in_buffer(ADAPTER *a, void *adr, void *P, word length);
  31. void io_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e);
  32. void io_out(ADAPTER *a, void *adr, byte data);
  33. void io_outw(ADAPTER *a, void *adr, word data);
  34. void io_out_buffer(ADAPTER *a, void *adr, void *P, word length);
  35. void io_inc(ADAPTER *a, void *adr);
  36. static int diva_server_bri_test_int(card_t *card);
  37. static int bri_ISR (card_t* card);
  38. #define PLX_IOBASE 0
  39. #define DIVAS_IOBASE 1
  40. #define REG_DATA 0x00
  41. #define REG_ADDRLO 0x04
  42. #define REG_ADDRHI 0x0C
  43. #define REG_IOCTRL 0x10
  44. #define M_PCI_RESET 0x10
  45. byte UxCardPortIoIn(ux_diva_card_t *card, byte *base, int offset);
  46. word UxCardPortIoInW(ux_diva_card_t *card, byte *base, int offset);
  47. void UxCardPortIoOut(ux_diva_card_t *card, byte *base, int offset, byte);
  48. void UxCardPortIoOutW(ux_diva_card_t *card, byte *base, int offset, word);
  49. int DivasBRIInitPCI(card_t *card, dia_card_t *cfg);
  50. static
  51. int diva_server_bri_reset(card_t *card)
  52. {
  53. byte *DivasIOBase;
  54. word i;
  55. dword dwWait;
  56. UxCardLog(0);
  57. DPRINTF(("divas: resetting BRI adapter"));
  58. DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
  59. UxCardPortIoOut(card->hw, DivasIOBase, REG_IOCTRL, 0);
  60. for (i=0; i < 50000; i++)
  61. ;
  62. UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0);
  63. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 0);
  64. UxCardPortIoOutW(card->hw, DivasIOBase, REG_DATA  , 0);
  65. UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0xFF);
  66. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 0x0000);
  67. for (i=0; i<0x8000; i++)
  68. {
  69. UxCardPortIoOutW(card->hw, DivasIOBase, REG_DATA , 0);
  70. }
  71. for (dwWait=0; dwWait < 0x00FFFFFF; dwWait++)
  72. ;
  73. UxCardMemDetach(card->hw, DivasIOBase);
  74. return 0;
  75. }
  76. static
  77. void diva_server_bri_reset_int(card_t *card)
  78. {
  79. byte *DivasIOBase = NULL;
  80. DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
  81. UxCardPortIoOut(card->hw, DivasIOBase, REG_IOCTRL, 0x08);
  82. UxCardMemDetach(card->hw, DivasIOBase);
  83. return;
  84. }
  85. static
  86. int diva_server_bri_start(card_t *card, byte *channels)
  87. {
  88. byte *DivasIOBase, *PLXIOBase;
  89. word wSig = 0;
  90. word i;
  91. dword dwSerialNum;
  92. byte bPLX9060 = FALSE;
  93. DPRINTF(("divas: starting Diva Server BRI card"));
  94. card->is_live = FALSE;
  95. DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
  96. UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0xFF);
  97. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 0x1E);
  98. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA  , 0);
  99. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA  , 0);
  100. UxCardPortIoOut(card->hw, DivasIOBase, REG_IOCTRL, 0x08);
  101. /* wait for signature to indicate card has started */
  102. for (i = 0; i < 300; i++)
  103. {
  104. UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0xFF);
  105. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 0x1E);
  106. wSig = UxCardPortIoInW(card->hw, DivasIOBase, REG_DATA);
  107. if (wSig == DIVAS_SIGNATURE)
  108. {
  109. DPRINTF(("divas: card started after %d ms", i * 10));
  110. break;
  111. }
  112. UxPause(10);
  113. }
  114. if (wSig != DIVAS_SIGNATURE)
  115. {
  116. DPRINTF(("divas: card failed to start (Sig=0x%x)", wSig));
  117. UxCardMemDetach(card->hw, DivasIOBase);
  118. return -1;
  119. }
  120. card->is_live = TRUE;
  121. UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0xFF);
  122. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 0x3F6);
  123. *channels = UxCardPortIoInW(card->hw, DivasIOBase, REG_DATA);
  124. UxCardMemDetach(card->hw, DivasIOBase);
  125. PLXIOBase = UxCardMemAttach(card->hw, PLX_IOBASE);
  126. bPLX9060 = UxCardPortIoInW(card->hw, PLXIOBase, 0x6C) | UxCardPortIoInW(card->hw, PLXIOBase, 0x6E);
  127. if (bPLX9060)
  128. dwSerialNum = (UxCardPortIoInW(card->hw, PLXIOBase, 0x1E) << 16) | 
  129. (UxCardPortIoInW(card->hw, PLXIOBase, 0x22));
  130. DPRINTF(("divas: PLX9060 in use. Serial number 0x%04X", dwSerialNum));
  131. }
  132. else
  133. {
  134. dwSerialNum = (UxCardPortIoInW(card->hw, PLXIOBase, 0x22) << 16) | 
  135. (UxCardPortIoInW(card->hw, PLXIOBase, 0x26));
  136. DPRINTF(("divas: PLX9050 in use. Serial number 0x%04X", dwSerialNum));
  137. }
  138. UxCardMemDetach(card->hw, PLXIOBase);
  139. card->serial_no = dwSerialNum;
  140. diva_server_bri_test_int(card);
  141. return 0;
  142. }
  143. static
  144. int diva_server_bri_load(card_t *card, dia_load_t *load)
  145. {
  146. byte *DivasIOBase;
  147. dword r3000_base;
  148. dword dwAddr, dwLength, i;
  149. word wTest, aWord;
  150. DPRINTF(("divas: loading Diva Server BRI card"));
  151. switch (load->code_type)
  152. {
  153. case DIA_CPU_CODE:
  154. DPRINTF(("divas: loading RISC %s", &load->code[0x80]));
  155. card->hw->features = GetProtFeatureValue((char *)&load->code[0x80]);
  156. DPRINTF(("divas: features 0x%x", card->hw->features));
  157. if (card->hw->features == 0xFFFF)
  158. {
  159. DPRINTF(("divas: invalid feature string failed loadn"));
  160. return -1;
  161. }
  162. r3000_base = 0;
  163. break;
  164. case DIA_DSP_CODE:
  165. DPRINTF(("divas: DSP code "%s"", load->code));
  166. if ((card->hw->features) && (!(card->hw->features & PROTCAP_TELINDUS)))
  167. {
  168. DPRINTF(("divas: only Telindus style binaries supported"));
  169. return -1;
  170. }
  171. if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
  172. {
  173. DPRINTF(("divas: V.90 DSP binary"));
  174. r3000_base = (0xBF790000 + (((sizeof(dword) + (sizeof(t_dsp_download_desc)* DSP_MAX_DOWNLOAD_COUNT)) + 3) & 0xFFFFFFFC));
  175. }
  176. else
  177. {
  178. DPRINTF(("divas: non-V.90 DSP binary"));
  179. r3000_base = (0xBF7A0000 + (((sizeof(dword) + (sizeof(t_dsp_download_desc)* DSP_MAX_DOWNLOAD_COUNT)) + 3) & 0xFFFFFFFC));
  180. }
  181. DPRINTF(("divas: loading at 0x%x", r3000_base));
  182. break;
  183. case DIA_TABLE_CODE:
  184. DPRINTF(("divas: TABLE code"));
  185. if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
  186. {
  187. r3000_base = 0xBF790000 + sizeof(dword);
  188. }
  189. else
  190. {
  191. r3000_base = 0xBF7A0000 + sizeof(dword);
  192. }
  193. break;
  194. case DIA_DLOAD_CNT:
  195. DPRINTF(("divas: COUNT code"));
  196. if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
  197. {
  198. r3000_base = 0xBF790000;
  199. }
  200. else
  201. {
  202. r3000_base = 0xBF7A0000;
  203. }
  204. break;
  205. default:
  206. DPRINTF(("divas: unknown code type %d", load->code_type));
  207. return -1;
  208. break;
  209. }
  210. DPRINTF(("divas: Writing %d bytes to adapter, address 0x%x", load->length, r3000_base));
  211. DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
  212. DPRINTF(("divas: Attached to 0x%04X", DivasIOBase));
  213. dwLength = load->length;
  214. for (i=0; i < dwLength; i++)
  215. {
  216. dwAddr = r3000_base + i;
  217. UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, dwAddr >> 16);
  218. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, dwAddr);
  219. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, load->code[i]);
  220. }
  221. DPRINTF(("divas: Verifying"));
  222. for (i=0; i<dwLength; i++)
  223. {
  224. dwAddr = r3000_base + i;
  225. UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, dwAddr >> 16);
  226. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, dwAddr);
  227. wTest = UxCardPortIoIn(card->hw, DivasIOBase, REG_DATA);
  228. aWord = load->code[i];
  229. if (wTest != aWord)
  230. {
  231. DPRINTF(("divas: load verify failed on byte %d", i));
  232. DPRINTF(("divas: RAM 0x%x   File 0x%x",wTest,aWord));
  233. UxCardMemDetach(card->hw, DivasIOBase);
  234. return -1;
  235. }
  236. }
  237. DPRINTF(("divas: Loaded and verified. Detaching from adapter"));
  238. UxCardMemDetach(card->hw, DivasIOBase);
  239. UxCardLog(0);
  240. return 0;
  241. }
  242. static
  243. int diva_server_bri_config(card_t *card, dia_config_t *config)
  244. {
  245. byte *DivasIOBase, i;
  246. DPRINTF(("divas: configuring Diva Server BRI card"));
  247. DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
  248. UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0xFF);
  249. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 8);
  250. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->tei);
  251. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 9);
  252. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->nt2);
  253. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 10);
  254. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->sig_flags);
  255. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 11);
  256. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->watchdog);
  257. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 12);
  258. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->permanent);
  259. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 13);
  260. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 0);
  261. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 14);
  262. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->stable_l2);
  263. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 15);
  264. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->no_order_check);
  265. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 16);
  266. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 0);
  267. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 17);
  268. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 0);
  269. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 18);
  270. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->low_channel);
  271. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 19);
  272. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->prot_version);
  273. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 20);
  274. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->crc4);
  275. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 21);
  276. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 0);
  277. if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
  278. {
  279. DPRINTF(("divas: Signifying V.90"));
  280. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 22);
  281. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 4);
  282. }
  283. else
  284. {
  285. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 22);
  286. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 0);
  287. }
  288. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 23);
  289. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, card->serial_no & 0xFF);
  290. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 24);
  291. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, (card->serial_no >> 8) & 0xFF);
  292. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 25);
  293. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, (card->serial_no >> 16) & 0xFF);
  294. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 26);
  295. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 21);
  296. for (i=0; i<32; i++)
  297. {
  298. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 32+i);
  299. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->terminal[0].oad[i]);
  300. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 64+i);
  301. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->terminal[0].osa[i]);
  302. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 96+i);
  303. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->terminal[0].spid[i]);
  304. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 128+i);
  305. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->terminal[1].oad[i]);
  306. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 160+i);
  307. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->terminal[1].osa[i]);
  308. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 192+i);
  309. UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->terminal[1].spid[i]);
  310. }
  311. UxCardMemDetach(card->hw, DivasIOBase);
  312. return 0;
  313. }
  314. void DivasBriPatch(card_t *card)
  315. {
  316. dword PLXIOBase = 0;
  317. dword DivasIOBase = 0;
  318. PLXIOBase = card->cfg.reset_base;
  319. DivasIOBase = card->cfg.io_base;
  320. if(card->hw == NULL)
  321. {
  322. DPRINTF(("Divas: BRI PATCH (PLX chip) card->hw is null"));
  323. return;
  324. }
  325. if (PLXIOBase == 0)
  326. {
  327. DPRINTF(("Divas: BRI (PLX chip) cannot be patched. The BRI adapter may"));
  328. DPRINTF(("Divas:   not function properly. If you do encounter problems,"));
  329. DPRINTF(("Divas:   ensure that your machine is using the latest BIOS."));
  330. return;
  331. }
  332. DPRINTF(("Divas: PLX I/O Base 0x%x", PLXIOBase));
  333. DPRINTF(("Divas: Divas I/O Base 0x%x", DivasIOBase));
  334. if (PLXIOBase & 0x80)
  335. {
  336. dword dwSize, dwSerialNum, dwCmd;
  337. boolean_t bPLX9060;
  338. word wSerHi, wSerLo;
  339. DPRINTF(("Divas: Patch required"));
  340. dwCmd = 0;
  341. UxPciConfigWrite(card->hw, 4, PCI_COMMAND, &dwCmd);
  342. PLXIOBase &= ~0x80;
  343. UxPciConfigWrite(card->hw, 4, PCI_BADDR1, &PLXIOBase);
  344. dwSize = 0xFFFFFFFF;
  345. UxPciConfigWrite(card->hw, 4, PCI_BADDR1, &dwSize);
  346. UxPciConfigRead(card->hw, 4, PCI_BADDR1, &dwSize);
  347. dwSize = (~ (dwSize & ~7)) + 1;
  348. DivasIOBase = PLXIOBase + dwSize;
  349. card->cfg.reset_base = PLXIOBase;
  350. card->cfg.io_base = DivasIOBase;
  351. UxPciConfigWrite(card->hw, 4, PCI_BADDR1, &card->cfg.reset_base);
  352. UxPciConfigWrite(card->hw, 4, PCI_BADDR2, &card->cfg.io_base);
  353. dwCmd = 5;
  354. UxPciConfigWrite(card->hw, 4, PCI_COMMAND, &dwCmd);
  355. bPLX9060 = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x6C) | 
  356.    UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x6E);
  357. if (bPLX9060)
  358. {
  359. wSerHi = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x1E);
  360. wSerLo = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x22);
  361. dwSerialNum = (wSerHi << 16) | wSerLo;
  362. UxCardLog(0);
  363. }
  364. else
  365. {
  366. wSerHi = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x22);
  367. wSerLo = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x26);
  368. dwSerialNum = (wSerHi << 16) | wSerLo;
  369. UxCardLog(0);
  370. }
  371. }
  372. else
  373. {
  374. word wSerHi, wSerLo;
  375. boolean_t bPLX9060;
  376. dword dwSerialNum;
  377. DPRINTF(("divas: No patch required"));
  378. bPLX9060 = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x6C) | 
  379.    UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x6E);
  380. if (bPLX9060)
  381. {
  382. wSerHi = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x1E);
  383. wSerLo = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x22);
  384. dwSerialNum = (wSerHi << 16) | wSerLo;
  385. }
  386. else
  387. {
  388. wSerHi = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x22);
  389. wSerLo = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x26);
  390. dwSerialNum = (wSerHi << 16) | wSerLo;
  391. }
  392. }
  393. DPRINTF(("Divas: After patching:"));
  394. DPRINTF(("Divas: PLX I/O Base 0x%x", PLXIOBase));
  395. DPRINTF(("Divas: Divas I/O Base 0x%x", DivasIOBase));
  396. }
  397. #define TEST_INT_DIVAS_BRI 0x12
  398. static
  399. int diva_server_bri_test_int(card_t *card)
  400. {
  401. boolean_t bPLX9060 = FALSE;
  402. byte *PLXIOBase = NULL, *DivasIOBase = NULL;
  403. DPRINTF(("divas: test interrupt for Diva Server BRI card"));
  404. PLXIOBase = UxCardMemAttach(card->hw, PLX_IOBASE);
  405. bPLX9060 = UxCardPortIoInW(card->hw, PLXIOBase, 0x6C) || UxCardPortIoInW(card->hw, PLXIOBase, 0x6E);
  406. if (bPLX9060)
  407. { /* PLX9060 */
  408. UxCardPortIoOut(card->hw, PLXIOBase, 0x69, 0x09);
  409. }
  410. else
  411. { /* PLX9050 */
  412. UxCardPortIoOut(card->hw, PLXIOBase, 0x4C, 0x41);
  413. }
  414. card->test_int_pend = TEST_INT_DIVAS_BRI;
  415. UxCardMemDetach(card->hw, PLXIOBase);
  416. DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
  417. UxCardPortIoOut(card->hw, DivasIOBase, REG_IOCTRL, 0x89);
  418. UxCardMemDetach(card->hw, DivasIOBase);
  419. return 0;
  420. }
  421. static
  422. int diva_server_bri_mem_get(card_t *card, mem_block_t *mem_block)
  423. {
  424. dword user_addr = mem_block->addr;
  425. word length = 0;
  426. dword addr;
  427. word i;
  428. byte *DivasIOBase;
  429. DPRINTF(("divas: Retrieving memory from 0x%x", user_addr));
  430. DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
  431. addr = user_addr;
  432. for (i=0; i < (16 * 8); i++)
  433. {
  434. addr = user_addr + i;
  435. UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, addr >> 16);
  436. UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, (word) addr);
  437. mem_block->data[i] = UxCardPortIoIn(card->hw, DivasIOBase, REG_DATA);
  438. length++;
  439. }
  440. UxCardMemDetach(card->hw, DivasIOBase);
  441. return length;
  442. }
  443. int DivasBriInit(card_t *card, dia_card_t *cfg)
  444. {
  445. DPRINTF(("divas: initialise Diva Server BRI card"));
  446. if (DivasBRIInitPCI(card, cfg) == -1)
  447. {
  448. return -1;
  449. }
  450. card->card_reset  = diva_server_bri_reset;
  451. card->card_start  = diva_server_bri_start;
  452. card->card_load   = diva_server_bri_load;
  453. card->card_config = diva_server_bri_config;
  454. card->reset_int  = diva_server_bri_reset_int;
  455. card->card_mem_get  = diva_server_bri_mem_get;
  456. card->xlog_offset  = DIVAS_MAINT_OFFSET;
  457. card->out  = DivasOut;
  458. card->test_int  = DivasTestInt;
  459. card->dpc  = DivasDpc;
  460. card->clear_int  = DivasClearInt;
  461. card->card_isr  = bri_ISR;
  462. card->a.ram_out  = io_out;
  463. card->a.ram_outw  = io_outw;
  464. card->a.ram_out_buffer  = io_out_buffer;
  465. card->a.ram_inc  = io_inc;
  466. card->a.ram_in  = io_in;
  467. card->a.ram_inw  = io_inw;
  468. card->a.ram_in_buffer  = io_in_buffer;
  469. card->a.ram_look_ahead = io_look_ahead;
  470. return 0;
  471. }
  472. word GetProtFeatureValue(char *sw_id)
  473. {
  474. word features = 0;
  475. while ((*sw_id) && (sw_id[0] != '['))
  476. sw_id++;
  477. if (sw_id == NULL)
  478. {
  479. DPRINTF(("divas: no feature string present"));
  480. features = -1;
  481. }
  482. else
  483. {
  484. byte i, shifter;
  485. sw_id += 3;
  486. for (i=0, shifter=12; i<4; i++, shifter-=4)
  487. {
  488. if ((sw_id[i] >= '0') && (sw_id[i] <= '9'))
  489. {
  490. features |= (sw_id[i] - '0') << shifter;
  491. }
  492. else if ((sw_id[i] >= 'a') && (sw_id[i] <= 'f'))
  493. {
  494. features |= (sw_id[i] - 'a' + 10) << shifter;
  495. }
  496. else if ((sw_id[i] >= 'A') && (sw_id[i] <= 'F'))
  497. {
  498. features |= (sw_id[i] - 'A' + 10) << shifter;
  499. }
  500. else
  501. {
  502. DPRINTF(("divas: invalid feature string"));
  503. return -1;
  504. }
  505. }
  506. }
  507. return features;
  508. }
  509. int bri_ISR (card_t* card) 
  510. {
  511. int served = 0;
  512. byte *DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
  513. if (UxCardPortIoIn (card->hw, DivasIOBase, M_PCI_RESET) & 0x01) 
  514. {
  515. served = 1;
  516. card->int_pend  += 1;
  517. DivasDpcSchedule(); /* ISR DPC */
  518. UxCardPortIoOut (card->hw, DivasIOBase, M_PCI_RESET, 0x08);
  519. }
  520. UxCardMemDetach(card->hw, DivasIOBase);
  521. return (served != 0);
  522. }