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