Merge branch 'for-2.6.30' of git://linux-nfs.org/~bfields/linux
[linux-2.6] / 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  __iomem *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_fromio(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 __iomem *p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
93  WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2);
94  diva_os_wait (50) ;
95  WRITE_BYTE(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 __iomem *p;
105  dword volatile __iomem *cfgReg = (void __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
106  WRITE_DWORD(&cfgReg[3], 0);
107  WRITE_DWORD(&cfgReg[1], 0);
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 = (void __iomem *)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  WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2);
123  DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
124 }
125 static int load_pri_hardware (PISDN_ADAPTER IoAdapter) {
126  return (0);
127 }
128 /* --------------------------------------------------------------------------
129   PRI Adapter interrupt Service Routine
130    -------------------------------------------------------------------------- */
131 static int pri_ISR (struct _ISDN_ADAPTER* IoAdapter) {
132  byte __iomem *cfg = DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
133  if ( !(READ_DWORD(cfg) & 0x80000000) ) {
134   DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg);
135   return (0) ;
136  }
137  /*
138   clear interrupt line
139   */
140  WRITE_DWORD(cfg, (dword)~0x03E00000) ;
141  DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg);
142  IoAdapter->IrqCount++ ;
143  if ( IoAdapter->Initialized )
144  {
145   diva_os_schedule_soft_isr (&IoAdapter->isr_soft_isr);
146  }
147  return (1) ;
148 }
149 /* -------------------------------------------------------------------------
150   Disable interrupt in the card hardware
151   ------------------------------------------------------------------------- */
152 static void disable_pri_interrupt (PISDN_ADAPTER IoAdapter) {
153  dword volatile __iomem *cfgReg = (dword volatile __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter) ;
154  WRITE_DWORD(&cfgReg[3], 0);
155  WRITE_DWORD(&cfgReg[1], 0);
156  WRITE_DWORD(&cfgReg[0], (dword)(~0x03E00000)) ;
157  DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
158 }
159 /* -------------------------------------------------------------------------
160   Install entry points for PRI Adapter
161   ------------------------------------------------------------------------- */
162 static void prepare_common_pri_functions (PISDN_ADAPTER IoAdapter) {
163  ADAPTER *a = &IoAdapter->a ;
164  a->ram_in           = mem_in ;
165  a->ram_inw          = mem_inw ;
166  a->ram_in_buffer    = mem_in_buffer ;
167  a->ram_look_ahead   = mem_look_ahead ;
168  a->ram_out          = mem_out ;
169  a->ram_outw         = mem_outw ;
170  a->ram_out_buffer   = mem_out_buffer ;
171  a->ram_inc          = mem_inc ;
172  a->ram_offset       = pri_ram_offset ;
173  a->ram_out_dw    = mem_out_dw;
174  a->ram_in_dw    = mem_in_dw;
175   a->istream_wakeup   = pr_stream;
176  IoAdapter->out      = pr_out ;
177  IoAdapter->dpc      = pr_dpc ;
178  IoAdapter->tst_irq  = scom_test_int ;
179  IoAdapter->clr_irq  = scom_clear_int ;
180  IoAdapter->pcm      = (struct pc_maint *)(MIPS_MAINT_OFFS
181                                         - MP_SHARED_RAM_OFFSET) ;
182  IoAdapter->load     = load_pri_hardware ;
183  IoAdapter->disIrq   = disable_pri_interrupt ;
184  IoAdapter->rstFnc   = reset_pri_hardware ;
185  IoAdapter->stop     = stop_pri_hardware ;
186  IoAdapter->trapFnc  = pri_cpu_trapped ;
187  IoAdapter->diva_isr_handler = pri_ISR;
188 }
189 /* -------------------------------------------------------------------------
190   Install entry points for PRI Adapter
191   ------------------------------------------------------------------------- */
192 void prepare_pri_functions (PISDN_ADAPTER IoAdapter) {
193  IoAdapter->MemorySize = MP_MEMORY_SIZE ;
194  prepare_common_pri_functions (IoAdapter) ;
195  diva_os_prepare_pri_functions (IoAdapter);
196 }
197 /* -------------------------------------------------------------------------
198   Install entry points for PRI Rev.2 Adapter
199   ------------------------------------------------------------------------- */
200 void prepare_pri2_functions (PISDN_ADAPTER IoAdapter) {
201  IoAdapter->MemorySize = MP2_MEMORY_SIZE ;
202  prepare_common_pri_functions (IoAdapter) ;
203  diva_os_prepare_pri2_functions (IoAdapter);
204 }
205 /* ------------------------------------------------------------------------- */