os_bri.c 20 KB

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