os_pri.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053
  1. /* $Id: os_pri.c,v 1.32 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_pri.h"
  14. #include "diva_pci.h"
  15. #include "mi_pc.h"
  16. #include "pc_maint.h"
  17. #include "dsp_tst.h"
  18. #include "diva_dma.h"
  19. #include "dsrv_pri.h"
  20. /* --------------------------------------------------------------------------
  21. OS Dependent part of XDI driver for DIVA PRI Adapter
  22. DSP detection/validation by Anthony Booth (Eicon Networks, www.eicon.com)
  23. -------------------------------------------------------------------------- */
  24. #define DIVA_PRI_NO_PCI_BIOS_WORKAROUND 1
  25. extern int diva_card_read_xlog(diva_os_xdi_adapter_t *a);
  26. /*
  27. ** IMPORTS
  28. */
  29. extern void prepare_pri_functions(PISDN_ADAPTER IoAdapter);
  30. extern void prepare_pri2_functions(PISDN_ADAPTER IoAdapter);
  31. extern void diva_xdi_display_adapter_features(int card);
  32. static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t *a);
  33. static int diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
  34. diva_xdi_um_cfg_cmd_t *cmd, int length);
  35. static int pri_get_serial_number(diva_os_xdi_adapter_t *a);
  36. static int diva_pri_stop_adapter(diva_os_xdi_adapter_t *a);
  37. static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t *a);
  38. /*
  39. ** Check card revision
  40. */
  41. static int pri_is_rev_2_card(int card_ordinal)
  42. {
  43. switch (card_ordinal) {
  44. case CARDTYPE_DIVASRV_P_30M_V2_PCI:
  45. case CARDTYPE_DIVASRV_VOICE_P_30M_V2_PCI:
  46. return (1);
  47. }
  48. return (0);
  49. }
  50. static void diva_pri_set_addresses(diva_os_xdi_adapter_t *a)
  51. {
  52. a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 0;
  53. a->resources.pci.mem_type_id[MEM_TYPE_CONTROL] = 2;
  54. a->resources.pci.mem_type_id[MEM_TYPE_CONFIG] = 4;
  55. a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 0;
  56. a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 2;
  57. a->resources.pci.mem_type_id[MEM_TYPE_CFG] = 4;
  58. a->resources.pci.mem_type_id[MEM_TYPE_PROM] = 3;
  59. a->xdi_adapter.Address = a->resources.pci.addr[0];
  60. a->xdi_adapter.Control = a->resources.pci.addr[2];
  61. a->xdi_adapter.Config = a->resources.pci.addr[4];
  62. a->xdi_adapter.ram = a->resources.pci.addr[0];
  63. a->xdi_adapter.ram += MP_SHARED_RAM_OFFSET;
  64. a->xdi_adapter.reset = a->resources.pci.addr[2];
  65. a->xdi_adapter.reset += MP_RESET;
  66. a->xdi_adapter.cfg = a->resources.pci.addr[4];
  67. a->xdi_adapter.cfg += MP_IRQ_RESET;
  68. a->xdi_adapter.sdram_bar = a->resources.pci.bar[0];
  69. a->xdi_adapter.prom = a->resources.pci.addr[3];
  70. }
  71. /*
  72. ** BAR0 - SDRAM, MP_MEMORY_SIZE, MP2_MEMORY_SIZE by Rev.2
  73. ** BAR1 - DEVICES, 0x1000
  74. ** BAR2 - CONTROL (REG), 0x2000
  75. ** BAR3 - FLASH (REG), 0x8000
  76. ** BAR4 - CONFIG (CFG), 0x1000
  77. */
  78. int diva_pri_init_card(diva_os_xdi_adapter_t *a)
  79. {
  80. int bar = 0;
  81. int pri_rev_2;
  82. unsigned long bar_length[5] = {
  83. MP_MEMORY_SIZE,
  84. 0x1000,
  85. 0x2000,
  86. 0x8000,
  87. 0x1000
  88. };
  89. pri_rev_2 = pri_is_rev_2_card(a->CardOrdinal);
  90. if (pri_rev_2) {
  91. bar_length[0] = MP2_MEMORY_SIZE;
  92. }
  93. /*
  94. Set properties
  95. */
  96. a->xdi_adapter.Properties = CardProperties[a->CardOrdinal];
  97. DBG_LOG(("Load %s", a->xdi_adapter.Properties.Name))
  98. /*
  99. First initialization step: get and check hardware resoures.
  100. Do not map resources and do not acecess card at this step
  101. */
  102. for (bar = 0; bar < 5; bar++) {
  103. a->resources.pci.bar[bar] =
  104. divasa_get_pci_bar(a->resources.pci.bus,
  105. a->resources.pci.func, bar,
  106. a->resources.pci.hdev);
  107. if (!a->resources.pci.bar[bar]
  108. || (a->resources.pci.bar[bar] == 0xFFFFFFF0)) {
  109. DBG_ERR(("A: invalid bar[%d]=%08x", bar,
  110. a->resources.pci.bar[bar]))
  111. return (-1);
  112. }
  113. }
  114. a->resources.pci.irq =
  115. (byte) divasa_get_pci_irq(a->resources.pci.bus,
  116. a->resources.pci.func,
  117. a->resources.pci.hdev);
  118. if (!a->resources.pci.irq) {
  119. DBG_ERR(("A: invalid irq"));
  120. return (-1);
  121. }
  122. /*
  123. Map all BAR's
  124. */
  125. for (bar = 0; bar < 5; bar++) {
  126. a->resources.pci.addr[bar] =
  127. divasa_remap_pci_bar(a, bar, a->resources.pci.bar[bar],
  128. bar_length[bar]);
  129. if (!a->resources.pci.addr[bar]) {
  130. DBG_ERR(("A: A(%d), can't map bar[%d]",
  131. a->controller, bar))
  132. diva_pri_cleanup_adapter(a);
  133. return (-1);
  134. }
  135. }
  136. /*
  137. Set all memory areas
  138. */
  139. diva_pri_set_addresses(a);
  140. /*
  141. Get Serial Number of this adapter
  142. */
  143. if (pri_get_serial_number(a)) {
  144. dword serNo;
  145. serNo = a->resources.pci.bar[1] & 0xffff0000;
  146. serNo |= ((dword) a->resources.pci.bus) << 8;
  147. serNo += (a->resources.pci.func + a->controller + 1);
  148. a->xdi_adapter.serialNo = serNo & ~0xFF000000;
  149. DBG_ERR(("A: A(%d) can't get Serial Number, generated serNo=%ld",
  150. a->controller, a->xdi_adapter.serialNo))
  151. }
  152. /*
  153. Initialize os objects
  154. */
  155. if (diva_os_initialize_spin_lock(&a->xdi_adapter.isr_spin_lock, "isr")) {
  156. diva_pri_cleanup_adapter(a);
  157. return (-1);
  158. }
  159. if (diva_os_initialize_spin_lock
  160. (&a->xdi_adapter.data_spin_lock, "data")) {
  161. diva_pri_cleanup_adapter(a);
  162. return (-1);
  163. }
  164. strcpy(a->xdi_adapter.req_soft_isr.dpc_thread_name, "kdivasprid");
  165. if (diva_os_initialize_soft_isr(&a->xdi_adapter.req_soft_isr,
  166. DIDpcRoutine, &a->xdi_adapter)) {
  167. diva_pri_cleanup_adapter(a);
  168. return (-1);
  169. }
  170. /*
  171. Do not initialize second DPC - only one thread will be created
  172. */
  173. a->xdi_adapter.isr_soft_isr.object =
  174. a->xdi_adapter.req_soft_isr.object;
  175. /*
  176. Next step of card initialization:
  177. set up all interface pointers
  178. */
  179. a->xdi_adapter.Channels = CardProperties[a->CardOrdinal].Channels;
  180. a->xdi_adapter.e_max = CardProperties[a->CardOrdinal].E_info;
  181. a->xdi_adapter.e_tbl =
  182. diva_os_malloc(0, a->xdi_adapter.e_max * sizeof(E_INFO));
  183. if (!a->xdi_adapter.e_tbl) {
  184. diva_pri_cleanup_adapter(a);
  185. return (-1);
  186. }
  187. memset(a->xdi_adapter.e_tbl, 0x00, a->xdi_adapter.e_max * sizeof(E_INFO));
  188. a->xdi_adapter.a.io = &a->xdi_adapter;
  189. a->xdi_adapter.DIRequest = request;
  190. a->interface.cleanup_adapter_proc = diva_pri_cleanup_adapter;
  191. a->interface.cmd_proc = diva_pri_cmd_card_proc;
  192. if (pri_rev_2) {
  193. prepare_pri2_functions(&a->xdi_adapter);
  194. } else {
  195. prepare_pri_functions(&a->xdi_adapter);
  196. }
  197. a->dsp_mask = diva_pri_detect_dsps(a);
  198. /*
  199. Allocate DMA map
  200. */
  201. if (pri_rev_2) {
  202. diva_init_dma_map(a->resources.pci.hdev,
  203. (struct _diva_dma_map_entry **) &a->xdi_adapter.dma_map, 32);
  204. }
  205. /*
  206. Set IRQ handler
  207. */
  208. a->xdi_adapter.irq_info.irq_nr = a->resources.pci.irq;
  209. sprintf(a->xdi_adapter.irq_info.irq_name,
  210. "DIVA PRI %ld", (long) a->xdi_adapter.serialNo);
  211. if (diva_os_register_irq(a, a->xdi_adapter.irq_info.irq_nr,
  212. a->xdi_adapter.irq_info.irq_name)) {
  213. diva_pri_cleanup_adapter(a);
  214. return (-1);
  215. }
  216. a->xdi_adapter.irq_info.registered = 1;
  217. diva_log_info("%s IRQ:%d SerNo:%d", a->xdi_adapter.Properties.Name,
  218. a->resources.pci.irq, a->xdi_adapter.serialNo);
  219. return (0);
  220. }
  221. static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t *a)
  222. {
  223. int bar = 0;
  224. /*
  225. Stop Adapter if adapter is running
  226. */
  227. if (a->xdi_adapter.Initialized) {
  228. diva_pri_stop_adapter(a);
  229. }
  230. /*
  231. Remove ISR Handler
  232. */
  233. if (a->xdi_adapter.irq_info.registered) {
  234. diva_os_remove_irq(a, a->xdi_adapter.irq_info.irq_nr);
  235. }
  236. a->xdi_adapter.irq_info.registered = 0;
  237. /*
  238. Step 1: unmap all BAR's, if any was mapped
  239. */
  240. for (bar = 0; bar < 5; bar++) {
  241. if (a->resources.pci.bar[bar]
  242. && a->resources.pci.addr[bar]) {
  243. divasa_unmap_pci_bar(a->resources.pci.addr[bar]);
  244. a->resources.pci.bar[bar] = 0;
  245. a->resources.pci.addr[bar] = NULL;
  246. }
  247. }
  248. /*
  249. Free OS objects
  250. */
  251. diva_os_cancel_soft_isr(&a->xdi_adapter.isr_soft_isr);
  252. diva_os_cancel_soft_isr(&a->xdi_adapter.req_soft_isr);
  253. diva_os_remove_soft_isr(&a->xdi_adapter.req_soft_isr);
  254. a->xdi_adapter.isr_soft_isr.object = NULL;
  255. diva_os_destroy_spin_lock(&a->xdi_adapter.isr_spin_lock, "rm");
  256. diva_os_destroy_spin_lock(&a->xdi_adapter.data_spin_lock, "rm");
  257. /*
  258. Free memory accupied by XDI adapter
  259. */
  260. if (a->xdi_adapter.e_tbl) {
  261. diva_os_free(0, a->xdi_adapter.e_tbl);
  262. a->xdi_adapter.e_tbl = NULL;
  263. }
  264. a->xdi_adapter.Channels = 0;
  265. a->xdi_adapter.e_max = 0;
  266. /*
  267. Free adapter DMA map
  268. */
  269. diva_free_dma_map(a->resources.pci.hdev,
  270. (struct _diva_dma_map_entry *) a->xdi_adapter.
  271. dma_map);
  272. a->xdi_adapter.dma_map = NULL;
  273. /*
  274. Detach this adapter from debug driver
  275. */
  276. return (0);
  277. }
  278. /*
  279. ** Activate On Board Boot Loader
  280. */
  281. static int diva_pri_reset_adapter(PISDN_ADAPTER IoAdapter)
  282. {
  283. dword i;
  284. struct mp_load __iomem *boot;
  285. if (!IoAdapter->Address || !IoAdapter->reset) {
  286. return (-1);
  287. }
  288. if (IoAdapter->Initialized) {
  289. DBG_ERR(("A: A(%d) can't reset PRI adapter - please stop first",
  290. IoAdapter->ANum))
  291. return (-1);
  292. }
  293. boot = (struct mp_load __iomem *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
  294. WRITE_DWORD(&boot->err, 0);
  295. DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
  296. IoAdapter->rstFnc(IoAdapter);
  297. diva_os_wait(10);
  298. boot = (struct mp_load __iomem *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
  299. i = READ_DWORD(&boot->live);
  300. diva_os_wait(10);
  301. if (i == READ_DWORD(&boot->live)) {
  302. DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
  303. DBG_ERR(("A: A(%d) CPU on PRI %ld is not alive!",
  304. IoAdapter->ANum, IoAdapter->serialNo))
  305. return (-1);
  306. }
  307. if (READ_DWORD(&boot->err)) {
  308. DBG_ERR(("A: A(%d) PRI %ld Board Selftest failed, error=%08lx",
  309. IoAdapter->ANum, IoAdapter->serialNo,
  310. READ_DWORD(&boot->err)))
  311. DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
  312. return (-1);
  313. }
  314. DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
  315. /*
  316. Forget all outstanding entities
  317. */
  318. IoAdapter->e_count = 0;
  319. if (IoAdapter->e_tbl) {
  320. memset(IoAdapter->e_tbl, 0x00,
  321. IoAdapter->e_max * sizeof(E_INFO));
  322. }
  323. IoAdapter->head = 0;
  324. IoAdapter->tail = 0;
  325. IoAdapter->assign = 0;
  326. IoAdapter->trapped = 0;
  327. memset(&IoAdapter->a.IdTable[0], 0x00,
  328. sizeof(IoAdapter->a.IdTable));
  329. memset(&IoAdapter->a.IdTypeTable[0], 0x00,
  330. sizeof(IoAdapter->a.IdTypeTable));
  331. memset(&IoAdapter->a.FlowControlIdTable[0], 0x00,
  332. sizeof(IoAdapter->a.FlowControlIdTable));
  333. memset(&IoAdapter->a.FlowControlSkipTable[0], 0x00,
  334. sizeof(IoAdapter->a.FlowControlSkipTable));
  335. memset(&IoAdapter->a.misc_flags_table[0], 0x00,
  336. sizeof(IoAdapter->a.misc_flags_table));
  337. memset(&IoAdapter->a.rx_stream[0], 0x00,
  338. sizeof(IoAdapter->a.rx_stream));
  339. memset(&IoAdapter->a.tx_stream[0], 0x00,
  340. sizeof(IoAdapter->a.tx_stream));
  341. memset(&IoAdapter->a.tx_pos[0], 0x00, sizeof(IoAdapter->a.tx_pos));
  342. memset(&IoAdapter->a.rx_pos[0], 0x00, sizeof(IoAdapter->a.rx_pos));
  343. return (0);
  344. }
  345. static int
  346. diva_pri_write_sdram_block(PISDN_ADAPTER IoAdapter,
  347. dword address,
  348. const byte *data, dword length, dword limit)
  349. {
  350. byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
  351. byte __iomem *mem = p;
  352. if (((address + length) >= limit) || !mem) {
  353. DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
  354. DBG_ERR(("A: A(%d) write PRI address=0x%08lx",
  355. IoAdapter->ANum, address + length))
  356. return (-1);
  357. }
  358. mem += address;
  359. /* memcpy_toio(), maybe? */
  360. while (length--) {
  361. WRITE_BYTE(mem++, *data++);
  362. }
  363. DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
  364. return (0);
  365. }
  366. static int
  367. diva_pri_start_adapter(PISDN_ADAPTER IoAdapter,
  368. dword start_address, dword features)
  369. {
  370. dword i;
  371. int started = 0;
  372. byte __iomem *p;
  373. struct mp_load __iomem *boot = (struct mp_load __iomem *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
  374. ADAPTER *a = &IoAdapter->a;
  375. if (IoAdapter->Initialized) {
  376. DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
  377. DBG_ERR(("A: A(%d) pri_start_adapter, adapter already running",
  378. IoAdapter->ANum))
  379. return (-1);
  380. }
  381. if (!boot) {
  382. DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
  383. DBG_ERR(("A: PRI %ld can't start, adapter not mapped",
  384. IoAdapter->serialNo))
  385. return (-1);
  386. }
  387. sprintf(IoAdapter->Name, "A(%d)", (int) IoAdapter->ANum);
  388. DBG_LOG(("A(%d) start PRI at 0x%08lx", IoAdapter->ANum,
  389. start_address))
  390. WRITE_DWORD(&boot->addr, start_address);
  391. WRITE_DWORD(&boot->cmd, 3);
  392. for (i = 0; i < 300; ++i) {
  393. diva_os_wait(10);
  394. if ((READ_DWORD(&boot->signature) >> 16) == 0x4447) {
  395. DBG_LOG(("A(%d) Protocol startup time %d.%02d seconds",
  396. IoAdapter->ANum, (i / 100), (i % 100)))
  397. started = 1;
  398. break;
  399. }
  400. }
  401. if (!started) {
  402. byte __iomem *p = (byte __iomem *)boot;
  403. dword TrapId;
  404. dword debug;
  405. TrapId = READ_DWORD(&p[0x80]);
  406. debug = READ_DWORD(&p[0x1c]);
  407. DBG_ERR(("A(%d) Adapter start failed 0x%08lx, TrapId=%08lx, debug=%08lx",
  408. IoAdapter->ANum, READ_DWORD(&boot->signature),
  409. TrapId, debug))
  410. DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
  411. if (IoAdapter->trapFnc) {
  412. (*(IoAdapter->trapFnc)) (IoAdapter);
  413. }
  414. IoAdapter->stop(IoAdapter);
  415. return (-1);
  416. }
  417. DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
  418. IoAdapter->Initialized = true;
  419. /*
  420. Check Interrupt
  421. */
  422. IoAdapter->IrqCount = 0;
  423. p = DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
  424. WRITE_DWORD(p, (dword)~0x03E00000);
  425. DIVA_OS_MEM_DETACH_CFG(IoAdapter, p);
  426. a->ReadyInt = 1;
  427. a->ram_out(a, &PR_RAM->ReadyInt, 1);
  428. for (i = 100; !IoAdapter->IrqCount && (i-- > 0); diva_os_wait(10));
  429. if (!IoAdapter->IrqCount) {
  430. DBG_ERR(("A: A(%d) interrupt test failed",
  431. IoAdapter->ANum))
  432. IoAdapter->Initialized = false;
  433. IoAdapter->stop(IoAdapter);
  434. return (-1);
  435. }
  436. IoAdapter->Properties.Features = (word) features;
  437. diva_xdi_display_adapter_features(IoAdapter->ANum);
  438. DBG_LOG(("A(%d) PRI adapter successfully started", IoAdapter->ANum))
  439. /*
  440. Register with DIDD
  441. */
  442. diva_xdi_didd_register_adapter(IoAdapter->ANum);
  443. return (0);
  444. }
  445. static void diva_pri_clear_interrupts(diva_os_xdi_adapter_t *a)
  446. {
  447. PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
  448. /*
  449. clear any pending interrupt
  450. */
  451. IoAdapter->disIrq(IoAdapter);
  452. IoAdapter->tst_irq(&IoAdapter->a);
  453. IoAdapter->clr_irq(&IoAdapter->a);
  454. IoAdapter->tst_irq(&IoAdapter->a);
  455. /*
  456. kill pending dpcs
  457. */
  458. diva_os_cancel_soft_isr(&IoAdapter->req_soft_isr);
  459. diva_os_cancel_soft_isr(&IoAdapter->isr_soft_isr);
  460. }
  461. /*
  462. ** Stop Adapter, but do not unmap/unregister - adapter
  463. ** will be restarted later
  464. */
  465. static int diva_pri_stop_adapter(diva_os_xdi_adapter_t *a)
  466. {
  467. PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
  468. int i = 100;
  469. if (!IoAdapter->ram) {
  470. return (-1);
  471. }
  472. if (!IoAdapter->Initialized) {
  473. DBG_ERR(("A: A(%d) can't stop PRI adapter - not running",
  474. IoAdapter->ANum))
  475. return (-1); /* nothing to stop */
  476. }
  477. IoAdapter->Initialized = 0;
  478. /*
  479. Disconnect Adapter from DIDD
  480. */
  481. diva_xdi_didd_remove_adapter(IoAdapter->ANum);
  482. /*
  483. Stop interrupts
  484. */
  485. a->clear_interrupts_proc = diva_pri_clear_interrupts;
  486. IoAdapter->a.ReadyInt = 1;
  487. IoAdapter->a.ram_inc(&IoAdapter->a, &PR_RAM->ReadyInt);
  488. do {
  489. diva_os_sleep(10);
  490. } while (i-- && a->clear_interrupts_proc);
  491. if (a->clear_interrupts_proc) {
  492. diva_pri_clear_interrupts(a);
  493. a->clear_interrupts_proc = NULL;
  494. DBG_ERR(("A: A(%d) no final interrupt from PRI adapter",
  495. IoAdapter->ANum))
  496. }
  497. IoAdapter->a.ReadyInt = 0;
  498. /*
  499. Stop and reset adapter
  500. */
  501. IoAdapter->stop(IoAdapter);
  502. return (0);
  503. }
  504. /*
  505. ** Process commands form configuration/download framework and from
  506. ** user mode
  507. **
  508. ** return 0 on success
  509. */
  510. static int
  511. diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
  512. diva_xdi_um_cfg_cmd_t *cmd, int length)
  513. {
  514. int ret = -1;
  515. if (cmd->adapter != a->controller) {
  516. DBG_ERR(("A: pri_cmd, invalid controller=%d != %d",
  517. cmd->adapter, a->controller))
  518. return (-1);
  519. }
  520. switch (cmd->command) {
  521. case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL:
  522. a->xdi_mbox.data_length = sizeof(dword);
  523. a->xdi_mbox.data =
  524. diva_os_malloc(0, a->xdi_mbox.data_length);
  525. if (a->xdi_mbox.data) {
  526. *(dword *) a->xdi_mbox.data =
  527. (dword) a->CardOrdinal;
  528. a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
  529. ret = 0;
  530. }
  531. break;
  532. case DIVA_XDI_UM_CMD_GET_SERIAL_NR:
  533. a->xdi_mbox.data_length = sizeof(dword);
  534. a->xdi_mbox.data =
  535. diva_os_malloc(0, a->xdi_mbox.data_length);
  536. if (a->xdi_mbox.data) {
  537. *(dword *) a->xdi_mbox.data =
  538. (dword) a->xdi_adapter.serialNo;
  539. a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
  540. ret = 0;
  541. }
  542. break;
  543. case DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG:
  544. a->xdi_mbox.data_length = sizeof(dword) * 9;
  545. a->xdi_mbox.data =
  546. diva_os_malloc(0, a->xdi_mbox.data_length);
  547. if (a->xdi_mbox.data) {
  548. int i;
  549. dword *data = (dword *) a->xdi_mbox.data;
  550. for (i = 0; i < 8; i++) {
  551. *data++ = a->resources.pci.bar[i];
  552. }
  553. *data++ = (dword) a->resources.pci.irq;
  554. a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
  555. ret = 0;
  556. }
  557. break;
  558. case DIVA_XDI_UM_CMD_RESET_ADAPTER:
  559. ret = diva_pri_reset_adapter(&a->xdi_adapter);
  560. break;
  561. case DIVA_XDI_UM_CMD_WRITE_SDRAM_BLOCK:
  562. ret = diva_pri_write_sdram_block(&a->xdi_adapter,
  563. cmd->command_data.
  564. write_sdram.offset,
  565. (byte *)&cmd[1],
  566. cmd->command_data.
  567. write_sdram.length,
  568. pri_is_rev_2_card(a->
  569. CardOrdinal)
  570. ? MP2_MEMORY_SIZE :
  571. MP_MEMORY_SIZE);
  572. break;
  573. case DIVA_XDI_UM_CMD_STOP_ADAPTER:
  574. ret = diva_pri_stop_adapter(a);
  575. break;
  576. case DIVA_XDI_UM_CMD_START_ADAPTER:
  577. ret = diva_pri_start_adapter(&a->xdi_adapter,
  578. cmd->command_data.start.
  579. offset,
  580. cmd->command_data.start.
  581. features);
  582. break;
  583. case DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES:
  584. a->xdi_adapter.features =
  585. cmd->command_data.features.features;
  586. a->xdi_adapter.a.protocol_capabilities =
  587. a->xdi_adapter.features;
  588. DBG_TRC(("Set raw protocol features (%08x)",
  589. a->xdi_adapter.features))
  590. ret = 0;
  591. break;
  592. case DIVA_XDI_UM_CMD_GET_CARD_STATE:
  593. a->xdi_mbox.data_length = sizeof(dword);
  594. a->xdi_mbox.data =
  595. diva_os_malloc(0, a->xdi_mbox.data_length);
  596. if (a->xdi_mbox.data) {
  597. dword *data = (dword *) a->xdi_mbox.data;
  598. if (!a->xdi_adapter.ram ||
  599. !a->xdi_adapter.reset ||
  600. !a->xdi_adapter.cfg) {
  601. *data = 3;
  602. } else if (a->xdi_adapter.trapped) {
  603. *data = 2;
  604. } else if (a->xdi_adapter.Initialized) {
  605. *data = 1;
  606. } else {
  607. *data = 0;
  608. }
  609. a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
  610. ret = 0;
  611. }
  612. break;
  613. case DIVA_XDI_UM_CMD_READ_XLOG_ENTRY:
  614. ret = diva_card_read_xlog(a);
  615. break;
  616. case DIVA_XDI_UM_CMD_READ_SDRAM:
  617. if (a->xdi_adapter.Address) {
  618. if (
  619. (a->xdi_mbox.data_length =
  620. cmd->command_data.read_sdram.length)) {
  621. if (
  622. (a->xdi_mbox.data_length +
  623. cmd->command_data.read_sdram.offset) <
  624. a->xdi_adapter.MemorySize) {
  625. a->xdi_mbox.data =
  626. diva_os_malloc(0,
  627. a->xdi_mbox.
  628. data_length);
  629. if (a->xdi_mbox.data) {
  630. byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(&a->xdi_adapter);
  631. byte __iomem *src = p;
  632. byte *dst = a->xdi_mbox.data;
  633. dword len = a->xdi_mbox.data_length;
  634. src += cmd->command_data.read_sdram.offset;
  635. while (len--) {
  636. *dst++ = READ_BYTE(src++);
  637. }
  638. a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
  639. DIVA_OS_MEM_DETACH_ADDRESS(&a->xdi_adapter, p);
  640. ret = 0;
  641. }
  642. }
  643. }
  644. }
  645. break;
  646. default:
  647. DBG_ERR(("A: A(%d) invalid cmd=%d", a->controller,
  648. cmd->command))
  649. }
  650. return (ret);
  651. }
  652. /*
  653. ** Get Serial Number
  654. */
  655. static int pri_get_serial_number(diva_os_xdi_adapter_t *a)
  656. {
  657. byte data[64];
  658. int i;
  659. dword len = sizeof(data);
  660. volatile byte __iomem *config;
  661. volatile byte __iomem *flash;
  662. byte c;
  663. /*
  664. * First set some GT6401x config registers before accessing the BOOT-ROM
  665. */
  666. config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
  667. c = READ_BYTE(&config[0xc3c]);
  668. if (!(c & 0x08)) {
  669. WRITE_BYTE(&config[0xc3c], c); /* Base Address enable register */
  670. }
  671. WRITE_BYTE(&config[LOW_BOOTCS_DREG], 0x00);
  672. WRITE_BYTE(&config[HI_BOOTCS_DREG], 0xFF);
  673. DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
  674. /*
  675. * Read only the last 64 bytes of manufacturing data
  676. */
  677. memset(data, '\0', len);
  678. flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter);
  679. for (i = 0; i < len; i++) {
  680. data[i] = READ_BYTE(&flash[0x8000 - len + i]);
  681. }
  682. DIVA_OS_MEM_DETACH_PROM(&a->xdi_adapter, flash);
  683. config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
  684. WRITE_BYTE(&config[LOW_BOOTCS_DREG], 0xFC); /* Disable FLASH EPROM access */
  685. WRITE_BYTE(&config[HI_BOOTCS_DREG], 0xFF);
  686. DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
  687. if (memcmp(&data[48], "DIVAserverPR", 12)) {
  688. #if !defined(DIVA_PRI_NO_PCI_BIOS_WORKAROUND) /* { */
  689. word cmd = 0, cmd_org;
  690. void *addr;
  691. dword addr1, addr3, addr4;
  692. byte Bus, Slot;
  693. void *hdev;
  694. addr4 = a->resources.pci.bar[4];
  695. addr3 = a->resources.pci.bar[3]; /* flash */
  696. addr1 = a->resources.pci.bar[1]; /* unused */
  697. DBG_ERR(("A: apply Compaq BIOS workaround"))
  698. DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
  699. data[0], data[1], data[2], data[3],
  700. data[4], data[5], data[6], data[7]))
  701. Bus = a->resources.pci.bus;
  702. Slot = a->resources.pci.func;
  703. hdev = a->resources.pci.hdev;
  704. PCIread(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);
  705. PCIwrite(Bus, Slot, 0x04, &cmd, sizeof(cmd), hdev);
  706. PCIwrite(Bus, Slot, 0x14, &addr4, sizeof(addr4), hdev);
  707. PCIwrite(Bus, Slot, 0x20, &addr1, sizeof(addr1), hdev);
  708. PCIwrite(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);
  709. addr = a->resources.pci.addr[1];
  710. a->resources.pci.addr[1] = a->resources.pci.addr[4];
  711. a->resources.pci.addr[4] = addr;
  712. addr1 = a->resources.pci.bar[1];
  713. a->resources.pci.bar[1] = a->resources.pci.bar[4];
  714. a->resources.pci.bar[4] = addr1;
  715. /*
  716. Try to read Flash again
  717. */
  718. len = sizeof(data);
  719. config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
  720. if (!(config[0xc3c] & 0x08)) {
  721. config[0xc3c] |= 0x08; /* Base Address enable register */
  722. }
  723. config[LOW_BOOTCS_DREG] = 0x00;
  724. config[HI_BOOTCS_DREG] = 0xFF;
  725. DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
  726. memset(data, '\0', len);
  727. flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter);
  728. for (i = 0; i < len; i++) {
  729. data[i] = flash[0x8000 - len + i];
  730. }
  731. DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter, flash);
  732. config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
  733. config[LOW_BOOTCS_DREG] = 0xFC;
  734. config[HI_BOOTCS_DREG] = 0xFF;
  735. DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
  736. if (memcmp(&data[48], "DIVAserverPR", 12)) {
  737. DBG_ERR(("A: failed to read serial number"))
  738. DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
  739. data[0], data[1], data[2], data[3],
  740. data[4], data[5], data[6], data[7]))
  741. return (-1);
  742. }
  743. #else /* } { */
  744. DBG_ERR(("A: failed to read DIVA signature word"))
  745. DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
  746. data[0], data[1], data[2], data[3],
  747. data[4], data[5], data[6], data[7]))
  748. DBG_LOG(("%02x:%02x:%02x:%02x", data[47], data[46],
  749. data[45], data[44]))
  750. #endif /* } */
  751. }
  752. a->xdi_adapter.serialNo =
  753. (data[47] << 24) | (data[46] << 16) | (data[45] << 8) |
  754. data[44];
  755. if (!a->xdi_adapter.serialNo
  756. || (a->xdi_adapter.serialNo == 0xffffffff)) {
  757. a->xdi_adapter.serialNo = 0;
  758. DBG_ERR(("A: failed to read serial number"))
  759. return (-1);
  760. }
  761. DBG_LOG(("Serial No. : %ld", a->xdi_adapter.serialNo))
  762. DBG_TRC(("Board Revision : %d.%02d", (int) data[41],
  763. (int) data[40]))
  764. DBG_TRC(("PLD revision : %d.%02d", (int) data[33],
  765. (int) data[32]))
  766. DBG_TRC(("Boot loader version : %d.%02d", (int) data[37],
  767. (int) data[36]))
  768. DBG_TRC(("Manufacturing Date : %d/%02d/%02d (yyyy/mm/dd)",
  769. (int) ((data[28] > 90) ? 1900 : 2000) +
  770. (int) data[28], (int) data[29], (int) data[30]))
  771. return (0);
  772. }
  773. void diva_os_prepare_pri2_functions(PISDN_ADAPTER IoAdapter)
  774. {
  775. }
  776. void diva_os_prepare_pri_functions(PISDN_ADAPTER IoAdapter)
  777. {
  778. }
  779. /*
  780. ** Checks presence of DSP on board
  781. */
  782. static int
  783. dsp_check_presence(volatile byte __iomem *addr, volatile byte __iomem *data, int dsp)
  784. {
  785. word pattern;
  786. WRITE_WORD(addr, 0x4000);
  787. WRITE_WORD(data, DSP_SIGNATURE_PROBE_WORD);
  788. WRITE_WORD(addr, 0x4000);
  789. pattern = READ_WORD(data);
  790. if (pattern != DSP_SIGNATURE_PROBE_WORD) {
  791. DBG_TRC(("W: DSP[%d] %04x(is) != %04x(should)",
  792. dsp, pattern, DSP_SIGNATURE_PROBE_WORD))
  793. return (-1);
  794. }
  795. WRITE_WORD(addr, 0x4000);
  796. WRITE_WORD(data, ~DSP_SIGNATURE_PROBE_WORD);
  797. WRITE_WORD(addr, 0x4000);
  798. pattern = READ_WORD(data);
  799. if (pattern != (word)~DSP_SIGNATURE_PROBE_WORD) {
  800. DBG_ERR(("A: DSP[%d] %04x(is) != %04x(should)",
  801. dsp, pattern, (word)~DSP_SIGNATURE_PROBE_WORD))
  802. return (-2);
  803. }
  804. DBG_TRC(("DSP[%d] present", dsp))
  805. return (0);
  806. }
  807. /*
  808. ** Check if DSP's are present and operating
  809. ** Information about detected DSP's is returned as bit mask
  810. ** Bit 0 - DSP1
  811. ** ...
  812. ** ...
  813. ** ...
  814. ** Bit 29 - DSP30
  815. */
  816. static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t *a)
  817. {
  818. byte __iomem *base;
  819. byte __iomem *p;
  820. dword ret = 0;
  821. dword row_offset[7] = {
  822. 0x00000000,
  823. 0x00000800, /* 1 - ROW 1 */
  824. 0x00000840, /* 2 - ROW 2 */
  825. 0x00001000, /* 3 - ROW 3 */
  826. 0x00001040, /* 4 - ROW 4 */
  827. 0x00000000 /* 5 - ROW 0 */
  828. };
  829. byte __iomem *dsp_addr_port;
  830. byte __iomem *dsp_data_port;
  831. byte row_state;
  832. int dsp_row = 0, dsp_index, dsp_num;
  833. if (!a->xdi_adapter.Control || !a->xdi_adapter.reset) {
  834. return (0);
  835. }
  836. p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
  837. WRITE_BYTE(p, _MP_RISC_RESET | _MP_DSP_RESET);
  838. DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
  839. diva_os_wait(5);
  840. base = DIVA_OS_MEM_ATTACH_CONTROL(&a->xdi_adapter);
  841. for (dsp_num = 0; dsp_num < 30; dsp_num++) {
  842. dsp_row = dsp_num / 7 + 1;
  843. dsp_index = dsp_num % 7;
  844. dsp_data_port = base;
  845. dsp_addr_port = base;
  846. dsp_data_port += row_offset[dsp_row];
  847. dsp_addr_port += row_offset[dsp_row];
  848. dsp_data_port += (dsp_index * 8);
  849. dsp_addr_port += (dsp_index * 8) + 0x80;
  850. if (!dsp_check_presence
  851. (dsp_addr_port, dsp_data_port, dsp_num + 1)) {
  852. ret |= (1 << dsp_num);
  853. }
  854. }
  855. DIVA_OS_MEM_DETACH_CONTROL(&a->xdi_adapter, base);
  856. p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
  857. WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2);
  858. DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
  859. diva_os_wait(5);
  860. /*
  861. Verify modules
  862. */
  863. for (dsp_row = 0; dsp_row < 4; dsp_row++) {
  864. row_state = ((ret >> (dsp_row * 7)) & 0x7F);
  865. if (row_state && (row_state != 0x7F)) {
  866. for (dsp_index = 0; dsp_index < 7; dsp_index++) {
  867. if (!(row_state & (1 << dsp_index))) {
  868. DBG_ERR(("A: MODULE[%d]-DSP[%d] failed",
  869. dsp_row + 1,
  870. dsp_index + 1))
  871. }
  872. }
  873. }
  874. }
  875. if (!(ret & 0x10000000)) {
  876. DBG_ERR(("A: ON BOARD-DSP[1] failed"))
  877. }
  878. if (!(ret & 0x20000000)) {
  879. DBG_ERR(("A: ON BOARD-DSP[2] failed"))
  880. }
  881. /*
  882. Print module population now
  883. */
  884. DBG_LOG(("+-----------------------+"))
  885. DBG_LOG(("| DSP MODULE POPULATION |"))
  886. DBG_LOG(("+-----------------------+"))
  887. DBG_LOG(("| 1 | 2 | 3 | 4 |"))
  888. DBG_LOG(("+-----------------------+"))
  889. DBG_LOG(("| %s | %s | %s | %s |",
  890. ((ret >> (0 * 7)) & 0x7F) ? "Y" : "N",
  891. ((ret >> (1 * 7)) & 0x7F) ? "Y" : "N",
  892. ((ret >> (2 * 7)) & 0x7F) ? "Y" : "N",
  893. ((ret >> (3 * 7)) & 0x7F) ? "Y" : "N"))
  894. DBG_LOG(("+-----------------------+"))
  895. DBG_LOG(("DSP's(present-absent):%08x-%08x", ret,
  896. ~ret & 0x3fffffff))
  897. return (ret);
  898. }