os_bri.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814
  1. /* $Id: os_bri.c,v 1.21 2004/03/21 17:26:01 armin Exp $ */
  2. #include "platform.h"
  3. #include "debuglib.h"
  4. #include "cardtype.h"
  5. #include "pc.h"
  6. #include "pr_pc.h"
  7. #include "di_defs.h"
  8. #include "dsp_defs.h"
  9. #include "di.h"
  10. #include "io.h"
  11. #include "xdi_msg.h"
  12. #include "xdi_adapter.h"
  13. #include "os_bri.h"
  14. #include "diva_pci.h"
  15. #include "mi_pc.h"
  16. #include "pc_maint.h"
  17. #include "dsrv_bri.h"
  18. /*
  19. ** IMPORTS
  20. */
  21. extern void prepare_maestra_functions(PISDN_ADAPTER IoAdapter);
  22. extern void diva_xdi_display_adapter_features(int card);
  23. extern int diva_card_read_xlog(diva_os_xdi_adapter_t *a);
  24. /*
  25. ** LOCALS
  26. */
  27. static int bri_bar_length[3] = {
  28. 0x80,
  29. 0x80,
  30. 0x20
  31. };
  32. static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t *a);
  33. static dword diva_bri_get_serial_number(diva_os_xdi_adapter_t *a);
  34. static int diva_bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
  35. diva_xdi_um_cfg_cmd_t *cmd, int length);
  36. static int diva_bri_reregister_io(diva_os_xdi_adapter_t *a);
  37. static int diva_bri_reset_adapter(PISDN_ADAPTER IoAdapter);
  38. static int diva_bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
  39. dword address,
  40. const byte *data, dword length);
  41. static int diva_bri_start_adapter(PISDN_ADAPTER IoAdapter,
  42. dword start_address, dword features);
  43. static int diva_bri_stop_adapter(diva_os_xdi_adapter_t *a);
  44. static void diva_bri_set_addresses(diva_os_xdi_adapter_t *a)
  45. {
  46. a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 0;
  47. a->resources.pci.mem_type_id[MEM_TYPE_CFG] = 1;
  48. a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 2;
  49. a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 1;
  50. a->resources.pci.mem_type_id[MEM_TYPE_PORT] = 2;
  51. a->resources.pci.mem_type_id[MEM_TYPE_CTLREG] = 2;
  52. a->xdi_adapter.ram = a->resources.pci.addr[0];
  53. a->xdi_adapter.cfg = a->resources.pci.addr[1];
  54. a->xdi_adapter.Address = a->resources.pci.addr[2];
  55. a->xdi_adapter.reset = a->xdi_adapter.cfg;
  56. a->xdi_adapter.port = a->xdi_adapter.Address;
  57. a->xdi_adapter.ctlReg = a->xdi_adapter.port + M_PCI_RESET;
  58. a->xdi_adapter.reset += 0x4C; /* PLX 9050 !! */
  59. }
  60. /*
  61. ** BAR0 - MEM Addr - 0x80 - NOT USED
  62. ** BAR1 - I/O Addr - 0x80
  63. ** BAR2 - I/O Addr - 0x20
  64. */
  65. int diva_bri_init_card(diva_os_xdi_adapter_t *a)
  66. {
  67. int bar;
  68. dword bar2 = 0, bar2_length = 0xffffffff;
  69. word cmd = 0, cmd_org;
  70. byte Bus, Slot;
  71. void *hdev;
  72. byte __iomem *p;
  73. /*
  74. Set properties
  75. */
  76. a->xdi_adapter.Properties = CardProperties[a->CardOrdinal];
  77. DBG_LOG(("Load %s", a->xdi_adapter.Properties.Name))
  78. /*
  79. Get resources
  80. */
  81. for (bar = 0; bar < 3; bar++) {
  82. a->resources.pci.bar[bar] =
  83. divasa_get_pci_bar(a->resources.pci.bus,
  84. a->resources.pci.func, bar,
  85. a->resources.pci.hdev);
  86. if (!a->resources.pci.bar[bar]) {
  87. DBG_ERR(("A: can't get BAR[%d]", bar))
  88. return (-1);
  89. }
  90. }
  91. a->resources.pci.irq =
  92. (byte) divasa_get_pci_irq(a->resources.pci.bus,
  93. a->resources.pci.func,
  94. a->resources.pci.hdev);
  95. if (!a->resources.pci.irq) {
  96. DBG_ERR(("A: invalid irq"));
  97. return (-1);
  98. }
  99. /*
  100. Get length of I/O bar 2 - it is different by older
  101. EEPROM version
  102. */
  103. Bus = a->resources.pci.bus;
  104. Slot = a->resources.pci.func;
  105. hdev = a->resources.pci.hdev;
  106. /*
  107. Get plain original values of the BAR2 CDM registers
  108. */
  109. PCIread(Bus, Slot, 0x18, &bar2, sizeof(bar2), hdev);
  110. PCIread(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);
  111. /*
  112. Disable device and get BAR2 length
  113. */
  114. PCIwrite(Bus, Slot, 0x04, &cmd, sizeof(cmd), hdev);
  115. PCIwrite(Bus, Slot, 0x18, &bar2_length, sizeof(bar2_length), hdev);
  116. PCIread(Bus, Slot, 0x18, &bar2_length, sizeof(bar2_length), hdev);
  117. /*
  118. Restore BAR2 and CMD registers
  119. */
  120. PCIwrite(Bus, Slot, 0x18, &bar2, sizeof(bar2), hdev);
  121. PCIwrite(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);
  122. /*
  123. Calculate BAR2 length
  124. */
  125. bar2_length = (~(bar2_length & ~7)) + 1;
  126. DBG_LOG(("BAR[2] length=%lx", bar2_length))
  127. /*
  128. Map and register resources
  129. */
  130. if (!(a->resources.pci.addr[0] =
  131. divasa_remap_pci_bar(a, 0, a->resources.pci.bar[0],
  132. bri_bar_length[0]))) {
  133. DBG_ERR(("A: BRI, can't map BAR[0]"))
  134. diva_bri_cleanup_adapter(a);
  135. return (-1);
  136. }
  137. sprintf(&a->port_name[0], "BRI %02x:%02x",
  138. a->resources.pci.bus, a->resources.pci.func);
  139. if (diva_os_register_io_port(a, 1, a->resources.pci.bar[1],
  140. bri_bar_length[1], &a->port_name[0], 1)) {
  141. DBG_ERR(("A: BRI, can't register BAR[1]"))
  142. diva_bri_cleanup_adapter(a);
  143. return (-1);
  144. }
  145. a->resources.pci.addr[1] = (void *) (unsigned long) a->resources.pci.bar[1];
  146. a->resources.pci.length[1] = bri_bar_length[1];
  147. if (diva_os_register_io_port(a, 1, a->resources.pci.bar[2],
  148. bar2_length, &a->port_name[0], 2)) {
  149. DBG_ERR(("A: BRI, can't register BAR[2]"))
  150. diva_bri_cleanup_adapter(a);
  151. return (-1);
  152. }
  153. a->resources.pci.addr[2] = (void *) (unsigned long) a->resources.pci.bar[2];
  154. a->resources.pci.length[2] = bar2_length;
  155. /*
  156. Set all memory areas
  157. */
  158. diva_bri_set_addresses(a);
  159. /*
  160. Get Serial Number
  161. */
  162. a->xdi_adapter.serialNo = diva_bri_get_serial_number(a);
  163. /*
  164. Register I/O ports with correct name now
  165. */
  166. if (diva_bri_reregister_io(a)) {
  167. diva_bri_cleanup_adapter(a);
  168. return (-1);
  169. }
  170. /*
  171. Initialize OS dependent objects
  172. */
  173. if (diva_os_initialize_spin_lock
  174. (&a->xdi_adapter.isr_spin_lock, "isr")) {
  175. diva_bri_cleanup_adapter(a);
  176. return (-1);
  177. }
  178. if (diva_os_initialize_spin_lock
  179. (&a->xdi_adapter.data_spin_lock, "data")) {
  180. diva_bri_cleanup_adapter(a);
  181. return (-1);
  182. }
  183. strcpy(a->xdi_adapter.req_soft_isr.dpc_thread_name, "kdivasbrid");
  184. if (diva_os_initialize_soft_isr(&a->xdi_adapter.req_soft_isr,
  185. DIDpcRoutine, &a->xdi_adapter)) {
  186. diva_bri_cleanup_adapter(a);
  187. return (-1);
  188. }
  189. /*
  190. Do not initialize second DPC - only one thread will be created
  191. */
  192. a->xdi_adapter.isr_soft_isr.object = a->xdi_adapter.req_soft_isr.object;
  193. /*
  194. Create entity table
  195. */
  196. a->xdi_adapter.Channels = CardProperties[a->CardOrdinal].Channels;
  197. a->xdi_adapter.e_max = CardProperties[a->CardOrdinal].E_info;
  198. a->xdi_adapter.e_tbl = diva_os_malloc(0, a->xdi_adapter.e_max * sizeof(E_INFO));
  199. if (!a->xdi_adapter.e_tbl) {
  200. diva_bri_cleanup_adapter(a);
  201. return (-1);
  202. }
  203. memset(a->xdi_adapter.e_tbl, 0x00, a->xdi_adapter.e_max * sizeof(E_INFO));
  204. /*
  205. Set up interface
  206. */
  207. a->xdi_adapter.a.io = &a->xdi_adapter;
  208. a->xdi_adapter.DIRequest = request;
  209. a->interface.cleanup_adapter_proc = diva_bri_cleanup_adapter;
  210. a->interface.cmd_proc = diva_bri_cmd_card_proc;
  211. p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
  212. outpp(p, 0x41);
  213. DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
  214. prepare_maestra_functions(&a->xdi_adapter);
  215. a->dsp_mask = 0x00000003;
  216. /*
  217. Set IRQ handler
  218. */
  219. a->xdi_adapter.irq_info.irq_nr = a->resources.pci.irq;
  220. sprintf(a->xdi_adapter.irq_info.irq_name, "DIVA BRI %ld",
  221. (long) a->xdi_adapter.serialNo);
  222. if (diva_os_register_irq(a, a->xdi_adapter.irq_info.irq_nr,
  223. a->xdi_adapter.irq_info.irq_name)) {
  224. diva_bri_cleanup_adapter(a);
  225. return (-1);
  226. }
  227. a->xdi_adapter.irq_info.registered = 1;
  228. diva_log_info("%s IRQ:%d SerNo:%d", a->xdi_adapter.Properties.Name,
  229. a->resources.pci.irq, a->xdi_adapter.serialNo);
  230. return (0);
  231. }
  232. static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t *a)
  233. {
  234. int i;
  235. if (a->xdi_adapter.Initialized) {
  236. diva_bri_stop_adapter(a);
  237. }
  238. /*
  239. Remove ISR Handler
  240. */
  241. if (a->xdi_adapter.irq_info.registered) {
  242. diva_os_remove_irq(a, a->xdi_adapter.irq_info.irq_nr);
  243. }
  244. a->xdi_adapter.irq_info.registered = 0;
  245. if (a->resources.pci.addr[0] && a->resources.pci.bar[0]) {
  246. divasa_unmap_pci_bar(a->resources.pci.addr[0]);
  247. a->resources.pci.addr[0] = NULL;
  248. a->resources.pci.bar[0] = 0;
  249. }
  250. for (i = 1; i < 3; i++) {
  251. if (a->resources.pci.addr[i] && a->resources.pci.bar[i]) {
  252. diva_os_register_io_port(a, 0,
  253. a->resources.pci.bar[i],
  254. a->resources.pci.
  255. length[i],
  256. &a->port_name[0], i);
  257. a->resources.pci.addr[i] = NULL;
  258. a->resources.pci.bar[i] = 0;
  259. }
  260. }
  261. /*
  262. Free OS objects
  263. */
  264. diva_os_cancel_soft_isr(&a->xdi_adapter.req_soft_isr);
  265. diva_os_cancel_soft_isr(&a->xdi_adapter.isr_soft_isr);
  266. diva_os_remove_soft_isr(&a->xdi_adapter.req_soft_isr);
  267. a->xdi_adapter.isr_soft_isr.object = NULL;
  268. diva_os_destroy_spin_lock(&a->xdi_adapter.isr_spin_lock, "rm");
  269. diva_os_destroy_spin_lock(&a->xdi_adapter.data_spin_lock, "rm");
  270. /*
  271. Free memory
  272. */
  273. if (a->xdi_adapter.e_tbl) {
  274. diva_os_free(0, a->xdi_adapter.e_tbl);
  275. a->xdi_adapter.e_tbl = NULL;
  276. }
  277. return (0);
  278. }
  279. void diva_os_prepare_maestra_functions(PISDN_ADAPTER IoAdapter)
  280. {
  281. }
  282. /*
  283. ** Get serial number
  284. */
  285. static dword diva_bri_get_serial_number(diva_os_xdi_adapter_t *a)
  286. {
  287. dword serNo = 0;
  288. byte __iomem *confIO;
  289. word serHi, serLo;
  290. word __iomem *confMem;
  291. confIO = DIVA_OS_MEM_ATTACH_CFG(&a->xdi_adapter);
  292. serHi = (word) (inppw(&confIO[0x22]) & 0x0FFF);
  293. serLo = (word) (inppw(&confIO[0x26]) & 0x0FFF);
  294. serNo = ((dword) serHi << 16) | (dword) serLo;
  295. DIVA_OS_MEM_DETACH_CFG(&a->xdi_adapter, confIO);
  296. if ((serNo == 0) || (serNo == 0xFFFFFFFF)) {
  297. DBG_FTL(("W: BRI use BAR[0] to get card serial number"))
  298. confMem = (word __iomem *)DIVA_OS_MEM_ATTACH_RAM(&a->xdi_adapter);
  299. serHi = (word) (READ_WORD(&confMem[0x11]) & 0x0FFF);
  300. serLo = (word) (READ_WORD(&confMem[0x13]) & 0x0FFF);
  301. serNo = (((dword) serHi) << 16) | ((dword) serLo);
  302. DIVA_OS_MEM_DETACH_RAM(&a->xdi_adapter, confMem);
  303. }
  304. DBG_LOG(("Serial Number=%ld", serNo))
  305. return (serNo);
  306. }
  307. /*
  308. ** Unregister I/O and register it with new name,
  309. ** based on Serial Number
  310. */
  311. static int diva_bri_reregister_io(diva_os_xdi_adapter_t *a)
  312. {
  313. int i;
  314. for (i = 1; i < 3; i++) {
  315. diva_os_register_io_port(a, 0, a->resources.pci.bar[i],
  316. a->resources.pci.length[i],
  317. &a->port_name[0], i);
  318. a->resources.pci.addr[i] = NULL;
  319. }
  320. sprintf(a->port_name, "DIVA BRI %ld",
  321. (long) a->xdi_adapter.serialNo);
  322. for (i = 1; i < 3; i++) {
  323. if (diva_os_register_io_port(a, 1, a->resources.pci.bar[i],
  324. a->resources.pci.length[i],
  325. &a->port_name[0], i)) {
  326. DBG_ERR(("A: failed to reregister BAR[%d]", i))
  327. return (-1);
  328. }
  329. a->resources.pci.addr[i] =
  330. (void *) (unsigned long) a->resources.pci.bar[i];
  331. }
  332. return (0);
  333. }
  334. /*
  335. ** Process command from user mode
  336. */
  337. static int
  338. diva_bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
  339. diva_xdi_um_cfg_cmd_t *cmd, int length)
  340. {
  341. int ret = -1;
  342. if (cmd->adapter != a->controller) {
  343. DBG_ERR(("A: pri_cmd, invalid controller=%d != %d",
  344. cmd->adapter, a->controller))
  345. return (-1);
  346. }
  347. switch (cmd->command) {
  348. case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL:
  349. a->xdi_mbox.data_length = sizeof(dword);
  350. a->xdi_mbox.data =
  351. diva_os_malloc(0, a->xdi_mbox.data_length);
  352. if (a->xdi_mbox.data) {
  353. *(dword *) a->xdi_mbox.data =
  354. (dword) a->CardOrdinal;
  355. a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
  356. ret = 0;
  357. }
  358. break;
  359. case DIVA_XDI_UM_CMD_GET_SERIAL_NR:
  360. a->xdi_mbox.data_length = sizeof(dword);
  361. a->xdi_mbox.data =
  362. diva_os_malloc(0, a->xdi_mbox.data_length);
  363. if (a->xdi_mbox.data) {
  364. *(dword *) a->xdi_mbox.data =
  365. (dword) a->xdi_adapter.serialNo;
  366. a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
  367. ret = 0;
  368. }
  369. break;
  370. case DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG:
  371. a->xdi_mbox.data_length = sizeof(dword) * 9;
  372. a->xdi_mbox.data =
  373. diva_os_malloc(0, a->xdi_mbox.data_length);
  374. if (a->xdi_mbox.data) {
  375. int i;
  376. dword *data = (dword *) a->xdi_mbox.data;
  377. for (i = 0; i < 8; i++) {
  378. *data++ = a->resources.pci.bar[i];
  379. }
  380. *data++ = (dword) a->resources.pci.irq;
  381. a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
  382. ret = 0;
  383. }
  384. break;
  385. case DIVA_XDI_UM_CMD_GET_CARD_STATE:
  386. a->xdi_mbox.data_length = sizeof(dword);
  387. a->xdi_mbox.data =
  388. diva_os_malloc(0, a->xdi_mbox.data_length);
  389. if (a->xdi_mbox.data) {
  390. dword *data = (dword *) a->xdi_mbox.data;
  391. if (!a->xdi_adapter.port) {
  392. *data = 3;
  393. } else if (a->xdi_adapter.trapped) {
  394. *data = 2;
  395. } else if (a->xdi_adapter.Initialized) {
  396. *data = 1;
  397. } else {
  398. *data = 0;
  399. }
  400. a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
  401. ret = 0;
  402. }
  403. break;
  404. case DIVA_XDI_UM_CMD_RESET_ADAPTER:
  405. ret = diva_bri_reset_adapter(&a->xdi_adapter);
  406. break;
  407. case DIVA_XDI_UM_CMD_WRITE_SDRAM_BLOCK:
  408. ret = diva_bri_write_sdram_block(&a->xdi_adapter,
  409. cmd->command_data.
  410. write_sdram.offset,
  411. (byte *)&cmd[1],
  412. cmd->command_data.
  413. write_sdram.length);
  414. break;
  415. case DIVA_XDI_UM_CMD_START_ADAPTER:
  416. ret = diva_bri_start_adapter(&a->xdi_adapter,
  417. cmd->command_data.start.
  418. offset,
  419. cmd->command_data.start.
  420. features);
  421. break;
  422. case DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES:
  423. a->xdi_adapter.features =
  424. cmd->command_data.features.features;
  425. a->xdi_adapter.a.protocol_capabilities =
  426. a->xdi_adapter.features;
  427. DBG_TRC(
  428. ("Set raw protocol features (%08x)",
  429. a->xdi_adapter.features)) ret = 0;
  430. break;
  431. case DIVA_XDI_UM_CMD_STOP_ADAPTER:
  432. ret = diva_bri_stop_adapter(a);
  433. break;
  434. case DIVA_XDI_UM_CMD_READ_XLOG_ENTRY:
  435. ret = diva_card_read_xlog(a);
  436. break;
  437. default:
  438. DBG_ERR(
  439. ("A: A(%d) invalid cmd=%d", a->controller,
  440. cmd->command))}
  441. return (ret);
  442. }
  443. static int diva_bri_reset_adapter(PISDN_ADAPTER IoAdapter)
  444. {
  445. byte __iomem *addrHi, *addrLo, *ioaddr;
  446. dword i;
  447. byte __iomem *Port;
  448. if (!IoAdapter->port) {
  449. return (-1);
  450. }
  451. if (IoAdapter->Initialized) {
  452. DBG_ERR(("A: A(%d) can't reset BRI adapter - please stop first",
  453. IoAdapter->ANum)) return (-1);
  454. }
  455. (*(IoAdapter->rstFnc)) (IoAdapter);
  456. diva_os_wait(100);
  457. Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
  458. addrHi = Port +
  459. ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
  460. addrLo = Port + ADDR;
  461. ioaddr = Port + DATA;
  462. /*
  463. recover
  464. */
  465. outpp(addrHi, (byte) 0);
  466. outppw(addrLo, (word) 0);
  467. outppw(ioaddr, (word) 0);
  468. /*
  469. clear shared memory
  470. */
  471. outpp(addrHi,
  472. (byte) (
  473. (IoAdapter->MemoryBase + IoAdapter->MemorySize -
  474. BRI_SHARED_RAM_SIZE) >> 16));
  475. outppw(addrLo, 0);
  476. for (i = 0; i < 0x8000; outppw(ioaddr, 0), ++i);
  477. diva_os_wait(100);
  478. /*
  479. clear signature
  480. */
  481. outpp(addrHi,
  482. (byte) (
  483. (IoAdapter->MemoryBase + IoAdapter->MemorySize -
  484. BRI_SHARED_RAM_SIZE) >> 16));
  485. outppw(addrLo, 0x1e);
  486. outpp(ioaddr, 0);
  487. outpp(ioaddr, 0);
  488. outpp(addrHi, (byte) 0);
  489. outppw(addrLo, (word) 0);
  490. outppw(ioaddr, (word) 0);
  491. DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
  492. /*
  493. Forget all outstanding entities
  494. */
  495. IoAdapter->e_count = 0;
  496. if (IoAdapter->e_tbl) {
  497. memset(IoAdapter->e_tbl, 0x00,
  498. IoAdapter->e_max * sizeof(E_INFO));
  499. }
  500. IoAdapter->head = 0;
  501. IoAdapter->tail = 0;
  502. IoAdapter->assign = 0;
  503. IoAdapter->trapped = 0;
  504. memset(&IoAdapter->a.IdTable[0], 0x00,
  505. sizeof(IoAdapter->a.IdTable));
  506. memset(&IoAdapter->a.IdTypeTable[0], 0x00,
  507. sizeof(IoAdapter->a.IdTypeTable));
  508. memset(&IoAdapter->a.FlowControlIdTable[0], 0x00,
  509. sizeof(IoAdapter->a.FlowControlIdTable));
  510. memset(&IoAdapter->a.FlowControlSkipTable[0], 0x00,
  511. sizeof(IoAdapter->a.FlowControlSkipTable));
  512. memset(&IoAdapter->a.misc_flags_table[0], 0x00,
  513. sizeof(IoAdapter->a.misc_flags_table));
  514. memset(&IoAdapter->a.rx_stream[0], 0x00,
  515. sizeof(IoAdapter->a.rx_stream));
  516. memset(&IoAdapter->a.tx_stream[0], 0x00,
  517. sizeof(IoAdapter->a.tx_stream));
  518. memset(&IoAdapter->a.tx_pos[0], 0x00, sizeof(IoAdapter->a.tx_pos));
  519. memset(&IoAdapter->a.rx_pos[0], 0x00, sizeof(IoAdapter->a.rx_pos));
  520. return (0);
  521. }
  522. static int
  523. diva_bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
  524. dword address, const byte *data, dword length)
  525. {
  526. byte __iomem *addrHi, *addrLo, *ioaddr;
  527. byte __iomem *Port;
  528. if (!IoAdapter->port) {
  529. return (-1);
  530. }
  531. Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
  532. addrHi = Port +
  533. ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
  534. addrLo = Port + ADDR;
  535. ioaddr = Port + DATA;
  536. while (length--) {
  537. outpp(addrHi, (word) (address >> 16));
  538. outppw(addrLo, (word) (address & 0x0000ffff));
  539. outpp(ioaddr, *data++);
  540. address++;
  541. }
  542. DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
  543. return (0);
  544. }
  545. static int
  546. diva_bri_start_adapter(PISDN_ADAPTER IoAdapter,
  547. dword start_address, dword features)
  548. {
  549. byte __iomem *Port;
  550. dword i, test;
  551. byte __iomem *addrHi, *addrLo, *ioaddr;
  552. int started = 0;
  553. ADAPTER *a = &IoAdapter->a;
  554. if (IoAdapter->Initialized) {
  555. DBG_ERR(
  556. ("A: A(%d) bri_start_adapter, adapter already running",
  557. IoAdapter->ANum)) return (-1);
  558. }
  559. if (!IoAdapter->port) {
  560. DBG_ERR(("A: A(%d) bri_start_adapter, adapter not mapped",
  561. IoAdapter->ANum)) return (-1);
  562. }
  563. sprintf(IoAdapter->Name, "A(%d)", (int) IoAdapter->ANum);
  564. DBG_LOG(("A(%d) start BRI", IoAdapter->ANum))
  565. Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
  566. addrHi = Port +
  567. ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
  568. addrLo = Port + ADDR;
  569. ioaddr = Port + DATA;
  570. outpp(addrHi,
  571. (byte) (
  572. (IoAdapter->MemoryBase + IoAdapter->MemorySize -
  573. BRI_SHARED_RAM_SIZE) >> 16));
  574. outppw(addrLo, 0x1e);
  575. outppw(ioaddr, 0x00);
  576. DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
  577. /*
  578. start the protocol code
  579. */
  580. Port = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
  581. outpp(Port, 0x08);
  582. DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, Port);
  583. Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
  584. addrHi = Port +
  585. ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
  586. addrLo = Port + ADDR;
  587. ioaddr = Port + DATA;
  588. /*
  589. wait for signature (max. 3 seconds)
  590. */
  591. for (i = 0; i < 300; ++i) {
  592. diva_os_wait(10);
  593. outpp(addrHi,
  594. (byte) (
  595. (IoAdapter->MemoryBase +
  596. IoAdapter->MemorySize -
  597. BRI_SHARED_RAM_SIZE) >> 16));
  598. outppw(addrLo, 0x1e);
  599. test = (dword) inppw(ioaddr);
  600. if (test == 0x4447) {
  601. DBG_LOG(
  602. ("Protocol startup time %d.%02d seconds",
  603. (i / 100), (i % 100)))
  604. started = 1;
  605. break;
  606. }
  607. }
  608. DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
  609. if (!started) {
  610. DBG_FTL(("A: A(%d) %s: Adapter selftest failed 0x%04X",
  611. IoAdapter->ANum, IoAdapter->Properties.Name,
  612. test))
  613. (*(IoAdapter->trapFnc)) (IoAdapter);
  614. return (-1);
  615. }
  616. IoAdapter->Initialized = 1;
  617. /*
  618. Check Interrupt
  619. */
  620. IoAdapter->IrqCount = 0;
  621. a->ReadyInt = 1;
  622. if (IoAdapter->reset) {
  623. Port = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
  624. outpp(Port, 0x41);
  625. DIVA_OS_MEM_DETACH_RESET(IoAdapter, Port);
  626. }
  627. a->ram_out(a, &PR_RAM->ReadyInt, 1);
  628. for (i = 0; ((!IoAdapter->IrqCount) && (i < 100)); i++) {
  629. diva_os_wait(10);
  630. }
  631. if (!IoAdapter->IrqCount) {
  632. DBG_ERR(
  633. ("A: A(%d) interrupt test failed",
  634. IoAdapter->ANum))
  635. IoAdapter->Initialized = 0;
  636. IoAdapter->stop(IoAdapter);
  637. return (-1);
  638. }
  639. IoAdapter->Properties.Features = (word) features;
  640. diva_xdi_display_adapter_features(IoAdapter->ANum);
  641. DBG_LOG(("A(%d) BRI adapter successfully started", IoAdapter->ANum))
  642. /*
  643. Register with DIDD
  644. */
  645. diva_xdi_didd_register_adapter(IoAdapter->ANum);
  646. return (0);
  647. }
  648. static void diva_bri_clear_interrupts(diva_os_xdi_adapter_t *a)
  649. {
  650. PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
  651. /*
  652. clear any pending interrupt
  653. */
  654. IoAdapter->disIrq(IoAdapter);
  655. IoAdapter->tst_irq(&IoAdapter->a);
  656. IoAdapter->clr_irq(&IoAdapter->a);
  657. IoAdapter->tst_irq(&IoAdapter->a);
  658. /*
  659. kill pending dpcs
  660. */
  661. diva_os_cancel_soft_isr(&IoAdapter->req_soft_isr);
  662. diva_os_cancel_soft_isr(&IoAdapter->isr_soft_isr);
  663. }
  664. /*
  665. ** Stop card
  666. */
  667. static int diva_bri_stop_adapter(diva_os_xdi_adapter_t *a)
  668. {
  669. PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
  670. int i = 100;
  671. if (!IoAdapter->port) {
  672. return (-1);
  673. }
  674. if (!IoAdapter->Initialized) {
  675. DBG_ERR(("A: A(%d) can't stop BRI adapter - not running",
  676. IoAdapter->ANum))
  677. return (-1); /* nothing to stop */
  678. }
  679. IoAdapter->Initialized = 0;
  680. /*
  681. Disconnect Adapter from DIDD
  682. */
  683. diva_xdi_didd_remove_adapter(IoAdapter->ANum);
  684. /*
  685. Stop interrupts
  686. */
  687. a->clear_interrupts_proc = diva_bri_clear_interrupts;
  688. IoAdapter->a.ReadyInt = 1;
  689. IoAdapter->a.ram_inc(&IoAdapter->a, &PR_RAM->ReadyInt);
  690. do {
  691. diva_os_sleep(10);
  692. } while (i-- && a->clear_interrupts_proc);
  693. if (a->clear_interrupts_proc) {
  694. diva_bri_clear_interrupts(a);
  695. a->clear_interrupts_proc = NULL;
  696. DBG_ERR(("A: A(%d) no final interrupt from BRI adapter",
  697. IoAdapter->ANum))
  698. }
  699. IoAdapter->a.ReadyInt = 0;
  700. /*
  701. Stop and reset adapter
  702. */
  703. IoAdapter->stop(IoAdapter);
  704. return (0);
  705. }