ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / isdn / hardware / eicon / s_pri.c
1
2 /*
3  *
4   Copyright (c) Eicon Networks, 2002.
5  *
6   This source file is supplied for the use with
7   Eicon Networks range of DIVA Server Adapters.
8  *
9   Eicon File Revision :    2.1
10  *
11   This program is free software; you can redistribute it and/or modify
12   it under the terms of the GNU General Public License as published by
13   the Free Software Foundation; either version 2, or (at your option)
14   any later version.
15  *
16   This program is distributed in the hope that it will be useful,
17   but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19   See the GNU General Public License for more details.
20  *
21   You should have received a copy of the GNU General Public License
22   along with this program; if not, write to the Free Software
23   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  *
25  */
26 #include "platform.h"
27 #include "di_defs.h"
28 #include "pc.h"
29 #include "pr_pc.h"
30 #include "di.h"
31 #include "mi_pc.h"
32 #include "pc_maint.h"
33 #include "divasync.h"
34 #include "io.h"
35 #include "helpers.h"
36 #include "dsrv_pri.h"
37 #include "dsp_defs.h"
38 /*****************************************************************************/
39 #define MAX_XLOG_SIZE  (64 * 1024)
40 /* -------------------------------------------------------------------------
41   Does return offset between ADAPTER->ram and real begin of memory
42   ------------------------------------------------------------------------- */
43 static dword pri_ram_offset (ADAPTER* a) {
44  return ((dword)MP_SHARED_RAM_OFFSET);
45 }
46 /* -------------------------------------------------------------------------
47   Recovery XLOG buffer from the card
48   ------------------------------------------------------------------------- */
49 static void pri_cpu_trapped (PISDN_ADAPTER IoAdapter) {
50  byte  *base ;
51  word *Xlog ;
52  dword   regs[4], TrapID, size ;
53  Xdesc   xlogDesc ;
54 /*
55  * check for trapped MIPS 46xx CPU, dump exception frame
56  */
57  base   = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
58  TrapID = READ_DWORD(&base[0x80]) ;
59  if ( (TrapID == 0x99999999) || (TrapID == 0x99999901) )
60  {
61   dump_trap_frame (IoAdapter, &base[0x90]) ;
62   IoAdapter->trapped = 1 ;
63  }
64  regs[0] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x70]);
65  regs[1] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x74]);
66  regs[2] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x78]);
67  regs[3] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x7c]);
68  regs[0] &= IoAdapter->MemorySize - 1 ;
69  if ( (regs[0] < IoAdapter->MemorySize - 1) )
70  {
71   if ( !(Xlog = (word *)diva_os_malloc (0, MAX_XLOG_SIZE)) ) {
72    DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base);
73    return ;
74   }
75   size = IoAdapter->MemorySize - regs[0] ;
76   if ( size > MAX_XLOG_SIZE )
77    size = MAX_XLOG_SIZE ;
78   memcpy (Xlog, &base[regs[0]], size) ;
79   xlogDesc.buf = Xlog ;
80   xlogDesc.cnt = READ_WORD(&base[regs[1] & (IoAdapter->MemorySize - 1)]) ;
81   xlogDesc.out = READ_WORD(&base[regs[2] & (IoAdapter->MemorySize - 1)]) ;
82   dump_xlog_buffer (IoAdapter, &xlogDesc) ;
83   diva_os_free (0, Xlog) ;
84   IoAdapter->trapped = 2 ;
85  }
86  DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base);
87 }
88 /* -------------------------------------------------------------------------
89   Hardware reset of PRI card
90   ------------------------------------------------------------------------- */
91 static void reset_pri_hardware (PISDN_ADAPTER IoAdapter) {
92  byte *p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
93  *p = _MP_RISC_RESET | _MP_LED1 | _MP_LED2 ;
94  diva_os_wait (50) ;
95  *p = 0x00 ;
96  diva_os_wait (50) ;
97  DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
98 }
99 /* -------------------------------------------------------------------------
100   Stop Card Hardware
101   ------------------------------------------------------------------------- */
102 static void stop_pri_hardware (PISDN_ADAPTER IoAdapter) {
103  dword i;
104  byte *p;
105  dword volatile *cfgReg = (dword volatile *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
106  cfgReg[3] = 0x00000000 ;
107  cfgReg[1] = 0x00000000 ;
108  DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
109  IoAdapter->a.ram_out (&IoAdapter->a, &RAM->SWReg, SWREG_HALT_CPU) ;
110  i = 0 ;
111  while ( (i < 100) && (IoAdapter->a.ram_in (&IoAdapter->a, &RAM->SWReg) != 0) )
112  {
113   diva_os_wait (1) ;
114   i++ ;
115  }
116  DBG_TRC(("%s: PRI stopped (%d)", IoAdapter->Name, i))
117  cfgReg = (dword volatile *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
118  WRITE_DWORD(&cfgReg[0],((dword)(~0x03E00000)));
119  DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
120  diva_os_wait (1) ;
121  p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
122  *p = _MP_RISC_RESET | _MP_LED1 | _MP_LED2 ;
123  DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
124 }
125 #if !defined(DIVA_USER_MODE_CARD_CONFIG) /* { */
126 /* -------------------------------------------------------------------------
127   Load protocol code to the PRI Card
128   ------------------------------------------------------------------------- */
129 #define DOWNLOAD_ADDR(IoAdapter) (IoAdapter->downloadAddr & (IoAdapter->MemorySize - 1))
130 static int pri_protocol_load (PISDN_ADAPTER IoAdapter) {
131  dword  FileLength ;
132  dword *File ;
133  dword *sharedRam ;
134  dword  Addr ;
135  byte *p;
136  if (!(File = (dword *)xdiLoadArchive (IoAdapter, &FileLength, 0))) {
137   return (0) ;
138  }
139  IoAdapter->features = diva_get_protocol_file_features ((byte*)File,
140                                         OFFS_PROTOCOL_ID_STRING,
141                                         IoAdapter->ProtocolIdString,
142                                         sizeof(IoAdapter->ProtocolIdString)) ;
143  IoAdapter->a.protocol_capabilities = IoAdapter->features ;
144  DBG_LOG(("Loading %s", IoAdapter->ProtocolIdString))
145  Addr = ((dword)(((byte *) File)[OFFS_PROTOCOL_END_ADDR]))
146    | (((dword)(((byte *) File)[OFFS_PROTOCOL_END_ADDR + 1])) << 8)
147    | (((dword)(((byte *) File)[OFFS_PROTOCOL_END_ADDR + 2])) << 16)
148    | (((dword)(((byte *) File)[OFFS_PROTOCOL_END_ADDR + 3])) << 24) ;
149         if ( Addr != 0 )
150  {
151   IoAdapter->DspCodeBaseAddr = (Addr + 3) & (~3) ;
152   IoAdapter->MaxDspCodeSize = (MP_UNCACHED_ADDR (IoAdapter->MemorySize)
153                             - IoAdapter->DspCodeBaseAddr) & (IoAdapter->MemorySize - 1) ;
154   Addr = IoAdapter->DspCodeBaseAddr ;
155   ((byte *) File)[OFFS_DSP_CODE_BASE_ADDR] = (byte) Addr ;
156   ((byte *) File)[OFFS_DSP_CODE_BASE_ADDR + 1] = (byte)(Addr >> 8) ;
157   ((byte *) File)[OFFS_DSP_CODE_BASE_ADDR + 2] = (byte)(Addr >> 16) ;
158   ((byte *) File)[OFFS_DSP_CODE_BASE_ADDR + 3] = (byte)(Addr >> 24) ;
159   IoAdapter->InitialDspInfo = 0x80 ;
160  }
161  else
162  {
163   if ( IoAdapter->features & PROTCAP_VOIP )
164    IoAdapter->MaxDspCodeSize = MP_VOIP_MAX_DSP_CODE_SIZE ;
165   else if ( IoAdapter->features & PROTCAP_V90D )
166    IoAdapter->MaxDspCodeSize = MP_V90D_MAX_DSP_CODE_SIZE ;
167   else
168    IoAdapter->MaxDspCodeSize = MP_ORG_MAX_DSP_CODE_SIZE ;
169   IoAdapter->DspCodeBaseAddr = MP_CACHED_ADDR (IoAdapter->MemorySize -
170                                                IoAdapter->MaxDspCodeSize) ;
171   IoAdapter->InitialDspInfo = (IoAdapter->MaxDspCodeSize
172                             - MP_ORG_MAX_DSP_CODE_SIZE) >> 14 ;
173  }
174  DBG_LOG(("DSP code base 0x%08lx, max size 0x%08lx (%08lx,%02x)",
175           IoAdapter->DspCodeBaseAddr, IoAdapter->MaxDspCodeSize,
176           Addr, IoAdapter->InitialDspInfo))
177  if ( FileLength > ((IoAdapter->DspCodeBaseAddr -
178                      MP_CACHED_ADDR (MP_PROTOCOL_OFFSET)) & (IoAdapter->MemorySize - 1)) )
179  {
180   xdiFreeFile (File);
181   DBG_FTL(("Protocol code '%s' too long (%ld)",
182            &IoAdapter->Protocol[0], FileLength))
183   return (0) ;
184  }
185  IoAdapter->downloadAddr = MP_UNCACHED_ADDR (MP_PROTOCOL_OFFSET) ;
186  p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
187  sharedRam = (dword *)(&p[DOWNLOAD_ADDR(IoAdapter)]);
188  memcpy (sharedRam, File, FileLength) ;
189  if ( memcmp (sharedRam, File, FileLength) )
190  {
191   DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
192   DBG_FTL(("%s: Memory test failed!", IoAdapter->Properties.Name))
193   xdiFreeFile (File);
194   return (0) ;
195  }
196  DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
197  xdiFreeFile (File);
198  return (1) ;
199 }
200 /******************************************************************************/
201 /*------------------------------------------------------------------
202   Dsp related definitions
203   ------------------------------------------------------------------ */
204 #define DSP_SIGNATURE_PROBE_WORD 0x5a5a
205 /*
206 **  Checks presence of DSP on board
207 */
208 static int
209 dsp_check_presence (volatile byte* addr, volatile byte* data, int dsp)
210 {
211   word pattern;
212   *(volatile word*)addr = 0x4000;
213   *(volatile word*)data = DSP_SIGNATURE_PROBE_WORD;
214   *(volatile word*)addr = 0x4000;
215   pattern = *(volatile word*)data;
216   if (pattern != DSP_SIGNATURE_PROBE_WORD) {
217     DBG_TRC(("W: DSP[%d] %04x(is) != %04x(should)",
218               dsp, pattern, DSP_SIGNATURE_PROBE_WORD))
219     return (-1);
220   }
221   *(volatile word*)addr = 0x4000;
222   *(volatile word*)data = ~DSP_SIGNATURE_PROBE_WORD;
223   *(volatile word*)addr = 0x4000;
224   pattern = *(volatile word*)data;
225   if (pattern != (word)~DSP_SIGNATURE_PROBE_WORD) {
226     DBG_ERR(("A: DSP[%d] %04x(is) != %04x(should)",
227               dsp, pattern, (word)~DSP_SIGNATURE_PROBE_WORD))
228     return (-2);
229   }
230   DBG_TRC (("DSP[%d] present", dsp))
231   return (0);
232 }
233 /*
234 **  Check if DSP's are present and operating
235 **  Information about detected DSP's is returned as bit mask
236 **  Bit 0  - DSP1
237 **  ...
238 **  ...
239 **  ...
240 **  Bit 29 - DSP30
241 */
242 static dword
243 diva_pri_detect_dsps (PISDN_ADAPTER IoAdapter)
244 {
245   byte* base;
246   byte* p;
247   dword ret = 0, DspCount = 0 ;
248   dword row_offset[] = {
249     0x00000000,
250     0x00000800, /* 1 - ROW 1 */
251     0x00000840, /* 2 - ROW 2 */
252     0x00001000, /* 3 - ROW 3 */
253     0x00001040, /* 4 - ROW 4 */
254     0x00000000  /* 5 - ROW 0 */
255   };
256   byte *dsp_addr_port, *dsp_data_port, row_state;
257   int dsp_row = 0, dsp_index, dsp_num;
258  IoAdapter->InitialDspInfo &= 0xffff ;
259  p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
260   if (!p)
261   {
262     DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
263     return (0);
264   }
265   *(volatile byte*)(p) = _MP_RISC_RESET | _MP_DSP_RESET;
266   DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
267   diva_os_wait (5) ;
268
269   base = DIVA_OS_MEM_ATTACH_CONTROL(IoAdapter);
270   
271   for (dsp_num = 0; dsp_num < 30; dsp_num++) {
272     dsp_row   = dsp_num / 7 + 1;
273     dsp_index = dsp_num % 7;
274     dsp_data_port = base;
275     dsp_addr_port = base;
276     dsp_data_port += row_offset[dsp_row];
277     dsp_addr_port += row_offset[dsp_row];
278     dsp_data_port += (dsp_index * 8);
279     dsp_addr_port += (dsp_index * 8) + 0x80;
280     if (!dsp_check_presence (dsp_addr_port, dsp_data_port, dsp_num+1)) {
281       ret |= (1 << dsp_num);
282    DspCount++ ;
283     }
284   }
285   DIVA_OS_MEM_DETACH_CONTROL(IoAdapter, base);
286
287   p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
288   *(volatile byte*)(p) = _MP_RISC_RESET | _MP_LED1 | _MP_LED2;
289   diva_os_wait (50) ;
290   /*
291     Verify modules
292   */
293   for (dsp_row = 0; dsp_row < 4; dsp_row++) {
294     row_state = (byte)((ret >> (dsp_row*7)) & 0x7F);
295     if (row_state && (row_state != 0x7F)) {
296       for (dsp_index = 0; dsp_index < 7; dsp_index++) {
297         if (!(row_state & (1 << dsp_index))) {
298           DBG_ERR (("A: MODULE[%d]-DSP[%d] failed", dsp_row+1, dsp_index+1))
299         }
300       }
301     }
302   }
303   if (!(ret & 0x10000000)) {
304     DBG_ERR (("A: ON BOARD-DSP[1] failed"))
305   }
306   if (!(ret & 0x20000000)) {
307     DBG_ERR (("A: ON BOARD-DSP[2] failed"))
308   }
309   /*
310     Print module population now
311   */
312   DBG_LOG(("+-----------------------+"))
313   DBG_LOG(("| DSP MODULE POPULATION |"))
314   DBG_LOG(("+-----------------------+"))
315   DBG_LOG(("|  1  |  2  |  3  |  4  |"))
316   DBG_LOG(("+-----------------------+"))
317   DBG_LOG(("|  %s  |  %s  |  %s  |  %s  |",
318     ((ret >> (0*7)) & 0x7F) ? "Y" : "N",
319     ((ret >> (1*7)) & 0x7F) ? "Y" : "N",
320     ((ret >> (2*7)) & 0x7F) ? "Y" : "N",
321     ((ret >> (3*7)) & 0x7F) ? "Y" : "N"))
322   DBG_LOG(("+-----------------------+"))
323   DBG_LOG(("DSP's(present-absent):%08x-%08x", ret, ~ret & 0x3fffffff))
324   *(volatile byte*)(p) = 0 ;
325   DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
326   diva_os_wait (50) ;
327  IoAdapter->InitialDspInfo |= DspCount << 16 ;
328   return (ret);
329 }
330 /* -------------------------------------------------------------------------
331   helper used to download dsp code toi PRI Card
332   ------------------------------------------------------------------------- */
333 static long pri_download_buffer (OsFileHandle *fp, long length, void **addr) {
334  PISDN_ADAPTER IoAdapter = (PISDN_ADAPTER)fp->sysLoadDesc ;
335  dword        *sharedRam ;
336  byte *p;
337  *addr = (void *)IoAdapter->downloadAddr ;
338  if ( ((dword) length) > IoAdapter->DspCodeBaseAddr +
339                          IoAdapter->MaxDspCodeSize - IoAdapter->downloadAddr )
340  {
341   DBG_FTL(("%s: out of card memory during DSP download (0x%X)",
342            IoAdapter->Properties.Name,
343            IoAdapter->downloadAddr + length))
344   return (-1) ;
345  }
346  p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
347  sharedRam = (dword *)(&p[DOWNLOAD_ADDR(IoAdapter)]);
348  if ( fp->sysFileRead (fp, sharedRam, length) != length ) {
349   DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
350   return (-1) ;
351  }
352  IoAdapter->downloadAddr += length ;
353  IoAdapter->downloadAddr  = (IoAdapter->downloadAddr + 3) & (~3) ;
354  DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
355  return (0) ;
356 }
357 /* -------------------------------------------------------------------------
358   Download DSP code to PRI Card
359   ------------------------------------------------------------------------- */
360 static dword pri_telindus_load (PISDN_ADAPTER IoAdapter) {
361  char                *error ;
362  OsFileHandle        *fp ;
363  t_dsp_portable_desc  download_table[DSP_MAX_DOWNLOAD_COUNT] ;
364  word                 download_count ;
365  dword               *sharedRam ;
366  dword                FileLength ;
367  byte *p;
368  if ( !(fp = OsOpenFile (DSP_TELINDUS_FILE)) )
369   return (0) ;
370  IoAdapter->downloadAddr = (IoAdapter->DspCodeBaseAddr
371                          + sizeof(dword) + sizeof(download_table) + 3) & (~3) ;
372  FileLength      = fp->sysFileSize ;
373  fp->sysLoadDesc = (void *)IoAdapter ;
374  fp->sysCardLoad = pri_download_buffer ;
375  download_count = DSP_MAX_DOWNLOAD_COUNT ;
376  memset (&download_table[0], '\0', sizeof(download_table)) ;
377 /*
378  * set start address for download (use autoincrement mode !)
379  */
380  error = dsp_read_file (fp, (word)(IoAdapter->cardType),
381                         &download_count, NULL, &download_table[0]) ;
382  if ( error )
383  {
384   DBG_FTL(("download file error: %s", error))
385   OsCloseFile (fp) ;
386   return (0) ;
387  }
388  OsCloseFile (fp) ;
389 /*
390  * store # of separate download files extracted from archive
391  */
392  IoAdapter->downloadAddr = IoAdapter->DspCodeBaseAddr ;
393  p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
394  sharedRam = (dword *)(&p[DOWNLOAD_ADDR(IoAdapter)]);
395  WRITE_DWORD(&(sharedRam[0]), (dword)download_count);
396  memcpy (&sharedRam[1], &download_table[0], sizeof(download_table)) ;
397  DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
398  return (FileLength) ;
399 }
400 /* -------------------------------------------------------------------------
401   Download PRI Card
402   ------------------------------------------------------------------------- */
403 #define MIN_DSPS 0x30000000
404 static int load_pri_hardware (PISDN_ADAPTER IoAdapter) {
405  dword           i ;
406  struct mp_load *boot = (struct mp_load *)DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
407  if ( IoAdapter->Properties.Card != CARD_MAEP ) {
408   DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
409   return (0) ;
410  }
411  boot->err = 0 ;
412 #if 0
413  IoAdapter->rstFnc (IoAdapter) ;
414 #else
415  if ( MIN_DSPS != (MIN_DSPS & diva_pri_detect_dsps(IoAdapter)) ) { /* makes reset */
416   DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
417   DBG_FTL(("%s: DSP error!", IoAdapter->Properties.Name))
418   return (0) ;
419  }
420 #endif
421 /*
422  * check if CPU is alive
423  */
424  diva_os_wait (10) ;
425  i = boot->live ;
426  diva_os_wait (10) ;
427  if ( i == boot->live )
428  {
429   DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
430   DBG_FTL(("%s: CPU is not alive!", IoAdapter->Properties.Name))
431   return (0) ;
432  }
433  if ( boot->err )
434  {
435   DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
436   DBG_FTL(("%s: Board Selftest failed!", IoAdapter->Properties.Name))
437   return (0) ;
438  }
439 /*
440  * download protocol and dsp files
441  */
442  if ( !xdiSetProtocol (IoAdapter, IoAdapter->ProtocolSuffix) ) {
443   DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
444   return (0) ;
445  }
446  if ( !pri_protocol_load (IoAdapter) ) {
447   DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
448   return (0) ;
449  }
450  if ( !pri_telindus_load (IoAdapter) ) {
451   DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
452   return (0) ;
453  }
454 /*
455  * copy configuration parameters
456  */
457  IoAdapter->ram += MP_SHARED_RAM_OFFSET ;
458  memset (boot + MP_SHARED_RAM_OFFSET, '\0', 256) ;
459  diva_configure_protocol (IoAdapter);
460 /*
461  * start adapter
462  */
463  boot->addr = MP_UNCACHED_ADDR (MP_PROTOCOL_OFFSET) ;
464  boot->cmd  = 3 ;
465 /*
466  * wait for signature in shared memory (max. 3 seconds)
467  */
468  for ( i = 0 ; i < 300 ; ++i )
469  {
470   diva_os_wait (10) ;
471   if ( (boot->signature >> 16) == 0x4447 )
472   {
473    DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
474    DBG_TRC(("Protocol startup time %d.%02d seconds",
475             (i / 100), (i % 100) ))
476    return (1) ;
477   }
478  }
479  DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
480  DBG_FTL(("%s: Adapter selftest failed (0x%04X)!",
481           IoAdapter->Properties.Name, boot->signature >> 16))
482  pri_cpu_trapped (IoAdapter) ;
483  return (0) ;
484 }
485 #else /* } { */
486 static int load_pri_hardware (PISDN_ADAPTER IoAdapter) {
487  return (0);
488 }
489 #endif /* } */
490 /* --------------------------------------------------------------------------
491   PRI Adapter interrupt Service Routine
492    -------------------------------------------------------------------------- */
493 static int pri_ISR (struct _ISDN_ADAPTER* IoAdapter) {
494  byte *cfg = DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
495  if ( !((READ_DWORD((dword *)cfg)) & 0x80000000) ) {
496   DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg);
497   return (0) ;
498  }
499  /*
500   clear interrupt line
501   */
502  WRITE_DWORD(((dword *)cfg), (dword)~0x03E00000) ;
503  DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg);
504  IoAdapter->IrqCount++ ;
505  if ( IoAdapter->Initialized )
506  {
507   diva_os_schedule_soft_isr (&IoAdapter->isr_soft_isr);
508  }
509  return (1) ;
510 }
511 /* -------------------------------------------------------------------------
512   Disable interrupt in the card hardware
513   ------------------------------------------------------------------------- */
514 static void disable_pri_interrupt (PISDN_ADAPTER IoAdapter) {
515  dword volatile *cfgReg = (dword volatile *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter) ;
516  cfgReg[3] = 0x00000000 ;
517  cfgReg[1] = 0x00000000 ;
518  WRITE_DWORD(&cfgReg[0], (dword)(~0x03E00000)) ;
519  DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
520 }
521 /* -------------------------------------------------------------------------
522   Install entry points for PRI Adapter
523   ------------------------------------------------------------------------- */
524 static void prepare_common_pri_functions (PISDN_ADAPTER IoAdapter) {
525  ADAPTER *a = &IoAdapter->a ;
526  a->ram_in           = mem_in ;
527  a->ram_inw          = mem_inw ;
528  a->ram_in_buffer    = mem_in_buffer ;
529  a->ram_look_ahead   = mem_look_ahead ;
530  a->ram_out          = mem_out ;
531  a->ram_outw         = mem_outw ;
532  a->ram_out_buffer   = mem_out_buffer ;
533  a->ram_inc          = mem_inc ;
534  a->ram_offset       = pri_ram_offset ;
535  a->ram_out_dw    = mem_out_dw;
536  a->ram_in_dw    = mem_in_dw;
537   a->istream_wakeup   = pr_stream;
538  IoAdapter->out      = pr_out ;
539  IoAdapter->dpc      = pr_dpc ;
540  IoAdapter->tst_irq  = scom_test_int ;
541  IoAdapter->clr_irq  = scom_clear_int ;
542  IoAdapter->pcm      = (struct pc_maint *)(MIPS_MAINT_OFFS
543                                         - MP_SHARED_RAM_OFFSET) ;
544  IoAdapter->load     = load_pri_hardware ;
545  IoAdapter->disIrq   = disable_pri_interrupt ;
546  IoAdapter->rstFnc   = reset_pri_hardware ;
547  IoAdapter->stop     = stop_pri_hardware ;
548  IoAdapter->trapFnc  = pri_cpu_trapped ;
549  IoAdapter->diva_isr_handler = pri_ISR;
550 }
551 /* -------------------------------------------------------------------------
552   Install entry points for PRI Adapter
553   ------------------------------------------------------------------------- */
554 void prepare_pri_functions (PISDN_ADAPTER IoAdapter) {
555  IoAdapter->MemorySize = MP_MEMORY_SIZE ;
556  prepare_common_pri_functions (IoAdapter) ;
557  diva_os_prepare_pri_functions (IoAdapter);
558 }
559 /* -------------------------------------------------------------------------
560   Install entry points for PRI Rev.2 Adapter
561   ------------------------------------------------------------------------- */
562 void prepare_pri2_functions (PISDN_ADAPTER IoAdapter) {
563  IoAdapter->MemorySize = MP2_MEMORY_SIZE ;
564  prepare_common_pri_functions (IoAdapter) ;
565  diva_os_prepare_pri2_functions (IoAdapter);
566 }
567 /* ------------------------------------------------------------------------- */